Mercurial > hg > Database > jungle-sharp
diff src/main/csharp/jp.ac.u-ryukyu.ie.cr/jungle/data/treemap/TreeMapNode.cs @ 0:dec15de2c6ff
first commit
author | Kazuma |
---|---|
date | Tue, 21 Jun 2016 17:11:12 +0900 |
parents | |
children | 5c58219da97e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/csharp/jp.ac.u-ryukyu.ie.cr/jungle/data/treemap/TreeMapNode.cs Tue Jun 21 17:11:12 2016 +0900 @@ -0,0 +1,338 @@ +using System.Collections; +using System; +using UnityEngine; + + +public abstract class TreeMapNode<K,V> +{ +// K,Vがnullableではないので受け付けない + // ジェネリックの扱いがJavaとちがうー>特にnullの扱いが面倒。 + protected K key; + protected V value; + protected TreeMapNode<K,V> right; + protected TreeMapNode<K,V> left; + + void Start(){ + key = default(K); + value = default(V); + } + + // Use this for initialization + public TreeMapNode (K key, V value) + { + this.key = key; + this.value = value; + } + + public TreeMapNode (K key, V value, TreeMapNode<K,V> left, TreeMapNode<K,V> right) + { + this.key = key; + this.value = value; + this.right = right; + this.left = left; + } + + public TreeMapNode<K,V> lefts () + { + return left; + } + + + public int compare(K compareKey, Comparer ctr) { + return ctr.Compare(compareKey, this.getKey()); + } + + public V get (K key, Comparer ctr) + { + TreeMapNode<K,V> cur = this; + int result = cur.compare (key, ctr); + while (cur.isNotEmpty ()) { + if (result > 0) { + cur = cur.rights (); + Debug.Log (cur); + } else if (result < 0) { + cur = cur.lefts (); + } else if (result == 0) { + if (cur != null) { + return cur.getValue (); + } + } + } + return default(V); // Optional<V>.ofNullable (null); + } + + + + public TreeMapNode<K,V> rights () { + return right; + } + + public K getKey () { + return key; + } + + public V getValue () { + return value; + } + + // may be to use Comparer?? + public TreeMapNode<K,V> put (K k, V v,Comparer ctr) { + + if (!isNotEmpty ()) { + return createNode (k, value, left, right); + } + + int result = compare (k,ctr); + if (result > 0) { + TreeMapNode<K,V> node = right.put (k, value,ctr); + node = createNode (key, this.value, left, node); + return node.insBalance (); + } else if (result < 0) { + TreeMapNode<K,V> node = left.put (k, value,ctr); + return createNode (key, this.value, node, right).insBalance (); + } + return createNode (key, value, left, right); + } + + public rebuildNode<K,V> delete (K key, TreeMapNode<K,V> parent, Comparer ctr, Rotate side) + { + if (this.isNotEmpty ()) { + rebuildNode<K,V> rebuildNode; + int result = compare(key, ctr); + if (result > 0) { + rebuildNode = right.delete (key, this, ctr, Rotate.R); + } else if (result < 0) { + rebuildNode = left.delete (key, this, ctr, Rotate.L); + } else { + rebuildNode = replaceNode (parent, ctr); + } + if (parent == null) { + return rebuildNode; + } + TreeMapNode<K,V> node = rebuildNode.getNode (); + if (rebuildNode.rebuilds ()) { + // ここのエラーは後で + return node.deleteBalance (parent, ctr); + } + TreeMapNode<K,V> newParent; + if (side == Rotate.L) { + newParent = parent.createNode (parent.getKey (), parent.getValue (), node, parent.rights ()); + } else { + newParent = parent.createNode (parent.getKey (), parent.getValue (), parent.lefts (), node); + } + return new rebuildNode<K,V> (false, newParent); + } + return null; + } + + public rebuildNode<K,V> deleteSubTreeMaxNode (TreeMapNode<K, V> parent, Comparer ctr, Rotate side) + { + rebuildNode<K,V> rebuildNode; + TreeMapNode<K, V> node; + if (rights ().isNotEmpty ()) {// 最大値のノードが取得できるまで潜る + rebuildNode = rights ().deleteSubTreeMaxNode (this, ctr, Rotate.R); + } else { + rebuildNode = this.replaceNode (parent, ctr); + } + if (parent == null) + return rebuildNode; + + if (rebuildNode.rebuilds ()) { + node = rebuildNode.getNode (); + return node.deleteBalance (parent, ctr); + } + if (side == Rotate.R) + node = parent.createNode (parent.getKey (), parent.getValue (), parent.lefts (), rebuildNode.getNode ()); + else + node = parent.createNode (parent.getKey (), parent.getValue (), rebuildNode.getNode (), parent.rights ()); + return new rebuildNode<K,V> (false, node); + } + + + public rebuildNode<K, V> deleteBalance (TreeMapNode<K, V> parent, Comparer ctr) + { + TreeMapNode<K, V> newNode = null; + if (!isRed ()) { + if (0 > compare (parent.getKey (), ctr)) { + bool rightChild = parent.lefts ().rights ().isRed (); + bool leftChild = parent.lefts ().lefts ().isRed (); + + if (!parent.isRed ()) { + if (!parent.lefts ().isRed ()) { + if (!rightChild && !leftChild) { + newNode = rebuildThree (parent, Rotate.R); + return new rebuildNode<K,V> (true, newNode); + } + if (rightChild) { + newNode = rebuildfive (parent, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } else { + newNode = rebuildsix (parent, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } + } else { // 左の子が赤 + newNode = rebuildTwo (parent, ctr, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } + } else { // 親が赤 + if (!rightChild && !leftChild) { + newNode = rebuildFour (parent, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } + if (rightChild) { + newNode = rebuildfive (parent, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } else { + newNode = rebuildsix (parent, Rotate.R); + return new rebuildNode<K,V> (false, newNode); + } + } + } else { + bool rightChild = parent.rights ().rights ().isRed (); + bool leftChild = parent.rights ().lefts ().isRed (); + + if (!parent.isRed ()) { // 親が黒 + if (!parent.rights ().isRed ()) { // 左の子が黒 + if (!rightChild && !leftChild) { + newNode = rebuildThree (parent, Rotate.L); + return new rebuildNode<K,V> (true, newNode); + } + if (rightChild) { + newNode = rebuildsix (parent, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } else { + newNode = rebuildfive (parent, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } + } else { // 左の子が赤 + newNode = rebuildTwo (parent, ctr, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } + } else { // 親が赤 + if (!rightChild && !leftChild) { + newNode = rebuildFour (parent, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } + if (rightChild) { + newNode = rebuildsix (parent, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } else { + newNode = rebuildfive (parent, Rotate.L); + return new rebuildNode<K,V> (false, newNode); + } + } + } + } + if (0 > (compare (parent.getKey (), ctr))) { + newNode = parent.createNode (parent.getKey (), parent.getValue (), parent.lefts (), this); + return new rebuildNode<K,V> (false, newNode); + } else { + newNode = parent.createNode (parent.getKey (), parent.getValue (), this, parent.rights ()); + return new rebuildNode<K,V> (false, newNode); + } + } + + protected TreeMapNode<K, V> rebuildTwo (TreeMapNode<K, V> parent, Comparer ctr, Rotate side) + { // case2 + if (side == Rotate.L) { // rotate Left + TreeMapNode<K, V> node = parent.rights (); + TreeMapNode<K, V> leftSubTreeRoot = node.createNode (parent.getKey (), parent.getValue (), this, node.lefts ()); // check + rebuildNode<K, V> rebuildNode = new rebuildNode<K,V> (false, leftSubTreeRoot); + rebuildNode<K, V> leftNodeRebuildNode = this.deleteBalance (rebuildNode.getNode (), ctr); + TreeMapNode<K, V> rightNode = node.rights (); + return parent.createNode (node.getKey (), node.getValue (), leftNodeRebuildNode.getNode (), rightNode); + } else { // rotate Right + TreeMapNode<K, V> node = parent.lefts (); + TreeMapNode<K, V> rightSubTreeRoot = node.createNode (parent.getKey (), parent.getValue (), node.rights (), this); + rebuildNode<K, V> rightSubTreeRebuildNode = new rebuildNode<K,V> (false, rightSubTreeRoot); + rebuildNode<K, V> rightNodeRebuildNode = this.deleteBalance (rightSubTreeRebuildNode.getNode (), ctr); + TreeMapNode<K, V> leftNode = node.lefts (); + return parent.createNode (node.getKey (), node.getValue (), leftNode, rightNodeRebuildNode.getNode ()); + } + } + + protected TreeMapNode<K, V> rebuildThree (TreeMapNode<K, V> parent, Rotate side) + { // case3 再帰 + if (side == Rotate.L) { + TreeMapNode<K, V> rightNode; + if (parent.rights ().isNotEmpty ()) + rightNode = new RedNode<K,V> (parent.rights ().getKey (), parent.rights ().getValue (), parent.rights ().lefts (), parent.rights ().rights ()); // check + else + rightNode = new EmptyNode<K,V> (); + return parent.createNode (parent.getKey (), parent.getValue (), this, rightNode); + } else { + TreeMapNode<K, V> leftNode; + if (parent.lefts ().isNotEmpty ()) + leftNode = new RedNode<K,V> (parent.lefts ().getKey (), parent.lefts ().getValue (), parent.lefts ().lefts (), parent.lefts ().rights ()); // check + else + leftNode = new EmptyNode<K,V> (); + return parent.createNode (parent.getKey (), parent.getValue (), leftNode, this); + } + } + + protected TreeMapNode<K, V> rebuildFour (TreeMapNode<K, V> parent, Rotate side) + { // case 4 + if (side == Rotate.R) { + TreeMapNode<K, V> leftNode = new RedNode<K,V> (parent.lefts ().getKey (), parent.lefts ().getValue (), parent.lefts ().lefts (), parent.lefts ().rights ()); + return new BlackNode<K,V> (parent.getKey (), parent.getValue (), leftNode, this); + } else { + TreeMapNode<K, V> rightNode = new RedNode<K,V> (parent.rights ().getKey (), parent.rights ().getValue (), parent.rights ().lefts (), parent.rights ().rights ()); + return new BlackNode<K,V> (parent.getKey (), parent.getValue (), this, rightNode); + } + } + + protected TreeMapNode<K, V> rebuildfive (TreeMapNode<K, V> parent, Rotate side) + { // case5 + if (side == Rotate.R) { // rotate Left + TreeMapNode<K, V> leftChild = new RedNode<K,V> (parent.lefts ().getKey (), parent.lefts ().getValue (), parent.lefts ().lefts (), parent.lefts ().rights ().lefts ()); + TreeMapNode<K, V> rightChild = parent.lefts ().rights ().rights (); + TreeMapNode<K, V> leftSubTreeRoot = new BlackNode<K,V> (parent.lefts ().rights ().getKey (), parent.lefts ().rights ().getValue (), leftChild, rightChild); + TreeMapNode<K, V> newParent = parent.createNode (parent.getKey (), parent.getValue (), leftSubTreeRoot, this); + return this.rebuildsix (newParent, Rotate.R); + } else { // rotate Right 修正済み + TreeMapNode<K, V> leftChild = parent.rights ().lefts ().lefts (); + TreeMapNode<K, V> rightChild = new RedNode<K,V> (parent.rights ().getKey (), parent.rights ().getValue (), parent.rights ().lefts ().rights (), parent.rights ().rights ()); + TreeMapNode<K, V> rightSubTreeRoot = new BlackNode<K,V> (parent.rights ().lefts ().getKey (), parent.rights ().lefts ().getValue (), leftChild, rightChild); + TreeMapNode<K, V> newParent = parent.createNode (parent.getKey (), parent.getValue (), this, rightSubTreeRoot); + return this.rebuildsix (newParent, Rotate.L); + } + } + + protected TreeMapNode<K, V> rebuildsix (TreeMapNode<K, V> parent, Rotate side) + { // case6 + if (side == Rotate.L) { // rotate Left + TreeMapNode<K, V> leftChild = parent.rights ().createNode (parent.getKey (), parent.getValue (), this, parent.rights ().lefts ()); // check + TreeMapNode<K, V> rightChild = new BlackNode<K,V> (parent.rights ().rights ().getKey (), parent.rights ().rights ().getValue (), parent.rights ().rights ().lefts (), parent.rights ().rights ().rights ()); + return parent.createNode (parent.rights ().getKey (), parent.rights ().getValue (), leftChild, rightChild); + } else { // rotate Right + TreeMapNode<K, V> leftChild = new BlackNode<K,V> (parent.lefts ().lefts ().getKey (), parent.lefts ().lefts ().getValue (), parent.lefts ().lefts ().lefts (), parent.lefts ().lefts ().rights ()); + TreeMapNode<K, V> rightChild = parent.lefts ().createNode (parent.getKey (), parent.getValue (), parent.lefts ().rights (), this); + return parent.createNode (parent.lefts ().getKey (), parent.lefts ().getValue (), leftChild, rightChild); + } + } + + + + + + + + + public abstract bool isNotEmpty (); + + public abstract TreeMapNode<K,V> createNode (K key, V value, TreeMapNode<K,V> left, TreeMapNode<K,V> right); + + public abstract TreeMapNode<K,V> insBalance (); + + + public abstract Rotate checkRotate (Rotate side); + + public abstract bool isRed (); + + public abstract rebuildNode<K,V> replaceNode (TreeMapNode<K,V> parent, Comparer ctr); + + public abstract rebuildNode<K,V> deleteNode (); + + // test method + public abstract int checkDepth (int count, int minCount); +}