Mercurial > hg > Members > shoshi > jungle > jungle-core
view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/Node.java @ 218:0b9807c1c6b4
delete TreeeMap warning
author | tatsuki |
---|---|
date | Tue, 01 Sep 2015 16:14:18 +0900 |
parents | 1b3661be3119 |
children | 3b31dd5e5a28 |
line wrap: on
line source
package jp.ac.u_ryukyu.ie.cr.jungle.data.treemap; import org.junit.Test; import java.util.Comparator; import java.util.Optional; public abstract class Node<K, V> { protected K key; protected V value; protected Node<K, V> right; protected Node<K, V> left; public Node(K key, V value) { this.key = key; this.value = value; } public Node(K key, V value, Node<K, V> left, Node<K, V> right) { this.key = key; this.value = value; this.right = right; this.left = left; } public Node<K, V> left() { return left; } @SuppressWarnings("unchecked") public int compare(K compareKey, Comparator ctr) { return ctr.compare(compareKey, this.getKey()); } public Optional<V> get(K key, Comparator ctr) { Node<K, V> cur = this; while (cur.isNotEmpty()) { int result = cur.compare(key, ctr); if (result > 0) cur = cur.right(); else if (result < 0) cur = cur.left(); else if (result == 0) return Optional.ofNullable(cur.getValue()); } return Optional.ofNullable(null); } public Node<K, V> right() { return right; } public K getKey() { return key; } public V getValue() { return value; } public Node<K, V> put(K k, V value, Comparator ctr) { if (!isNotEmpty()) { return createNode(k, value, left, right); } int result = compare(k, ctr); if (result > 0) { Node<K, V> node = right.put(k, value, ctr); node = createNode(key, this.value, left, node); return node.insBalance(); } else if (result < 0) { Node<K, V> node = left.put(k, value, ctr); return createNode(key, this.value, node, right).insBalance(); } return createNode(key, value, left, right); // equals } @SuppressWarnings("unchecked") public Node<K, V> delete(K key, Node<K, V> parent, Comparator ctr, Rotate side) throws RotateParent { if (this.isNotEmpty()) { int result = compare(key, ctr); try { Node<K, V> node = null; if (result > 0) { node = right.delete(key, this, ctr, Rotate.R); if (node == null) return null; if (parent == null) return node; } else if (result < 0) { node = left.delete(key, this, ctr, Rotate.L); if (node == null) return null; if (parent == null) return node; } else if (result == 0) { node = replaceNode(parent, ctr); if (parent == null)// equals return node; if (side == Rotate.R) return parent.createNode(parent.getKey(), parent.getValue(), parent.left(), node); else return parent.createNode(parent.getKey(), parent.getValue(), node, parent.right()); } if (side == Rotate.L) return parent.createNode(parent.getKey(), parent.getValue(), node, parent.right()); else return parent.createNode(parent.getKey(), parent.getValue(), parent.left(), node); } catch (RotateParent e) { Node<K, V> node = e.getParent(); if (parent != null) return node.deleteBalance(parent, ctr); return node; } } return null; // no key } @SuppressWarnings("unchecked") public Node<K, V> deleteSubTreeMaxNode(Node<K, V> parent, Comparator ctr, Rotate side) throws RotateParent { Node<K, V> node; try { if (right().isNotEmpty()) {//最大値のノードが取得できるまで潜る node = right().deleteSubTreeMaxNode(this, ctr, Rotate.R); } else { node = this.replaceNode(parent, ctr); } } catch (RotateParent e) { node = e.getParent(); if (parent == null) throw e; return node.deleteBalance(parent, ctr); } if (parent == null) return node; if (side == Rotate.R) return parent.createNode(parent.getKey(), parent.getValue(), parent.left(), node); else return parent.createNode(parent.getKey(), parent.getValue(), node, parent.right()); } public Node<K, V> deleteBalance(Node<K, V> parent, Comparator ctr) throws RotateParent { if (!isRed()) { if (0 > compare(parent.getKey(), ctr)) { //自身がどちらの子かを調べる boolean rightChild = parent.left().right().isRed(); boolean leftChild = parent.left().left().isRed(); if (!parent.isRed()) { //親が黒 if (!parent.left().isRed()) { //左の子が黒 if (!rightChild && !leftChild) throw new RotateParent(rebuildThree(parent, Rotate.R)); if (rightChild) return rebuildfive(parent, Rotate.R); else return rebuildsix(parent, Rotate.R); } else { //左の子が赤 return rebuildTwo(parent, ctr, Rotate.R); } } else { //親が赤 if (!rightChild && !leftChild) return rebuildFour(parent, Rotate.R); if (rightChild) return rebuildfive(parent, Rotate.R); else return rebuildsix(parent, Rotate.R); } } else { boolean rightChild = parent.right().right().isRed(); boolean leftChild = parent.right().left().isRed(); if (!parent.isRed()) { //親が黒 if (!parent.right().isRed()) { //左の子が黒 if (!rightChild && !leftChild) throw new RotateParent(rebuildThree(parent, Rotate.L)); if (rightChild) return rebuildsix(parent, Rotate.L); else return rebuildfive(parent, Rotate.L); } else { //左の子が赤 return rebuildTwo(parent, ctr, Rotate.L); } } else { //親が赤 if (!rightChild && !leftChild) return rebuildFour(parent, Rotate.L); if (rightChild) return rebuildsix(parent, Rotate.L); else return rebuildfive(parent, Rotate.L); } } } if (0 > (compare(parent.getKey(), ctr))) return parent.createNode(parent.getKey(), parent.getValue(), parent.left(), this); else return parent.createNode(parent.getKey(), parent.getValue(), this, parent.right()); } protected Node<K, V> rebuildTwo(Node<K, V> parent, Comparator ctr, Rotate side) throws RotateParent { // case2 if (side == Rotate.L) { // rotate Left Node<K, V> node = parent.right(); Node<K, V> leftSubTreeRoot = node.createNode(parent.getKey(), parent.getValue(), this, node.left()); // check Node<K, V> leftNode = this.deleteBalance(leftSubTreeRoot, ctr); Node<K, V> rightNode = node.right(); return parent.createNode(node.getKey(), node.getValue(), leftNode, rightNode); } else { // rotate Right Node<K, V> node = parent.left(); Node<K, V> rightSubTreeRoot = node.createNode(parent.getKey(), parent.getValue(), node.right(), this); Node<K, V> rightNode = this.deleteBalance(rightSubTreeRoot, ctr); Node<K, V> leftNode = node.left(); return parent.createNode(node.getKey(), node.getValue(), leftNode, rightNode); } } protected Node<K, V> rebuildThree(Node<K, V> parent, Rotate side) { // case3 再帰 if (side == Rotate.L) { Node<K, V> rightNode; if (parent.right().isNotEmpty()) rightNode = new RedNode<>(parent.right().getKey(), parent.right().getValue(), parent.right().left(), parent.right().right()); // check else rightNode = new EmptyNode<>(); return parent.createNode(parent.getKey(), parent.getValue(), this, rightNode); } else { Node<K, V> leftNode; if (parent.left().isNotEmpty()) leftNode = new RedNode<>(parent.left().getKey(), parent.left().getValue(), parent.left().left(), parent.left().right()); // check else leftNode = new EmptyNode<>(); return parent.createNode(parent.getKey(), parent.getValue(), leftNode, this); } } protected Node<K, V> rebuildFour(Node<K, V> parent, Rotate side) { //case 4 if (side == Rotate.R) { Node<K, V> leftNode = new RedNode<>(parent.left().getKey(), parent.left().getValue(), parent.left().left(), parent.left().right()); return new BlackNode<>(parent.getKey(), parent.getValue(), leftNode, this); } else { Node<K, V> rightNode = new RedNode<>(parent.right().getKey(), parent.right().getValue(), parent.right().left(), parent.right().right()); return new BlackNode<>(parent.getKey(), parent.getValue(), this, rightNode); } } protected Node<K, V> rebuildfive(Node<K, V> parent, Rotate side) { //case5 if (side == Rotate.R) { // rotate Left Node<K, V> leftChild = new RedNode<>(parent.left().getKey(), parent.left().getValue(), parent.left().left(), parent.left().right().left()); Node<K, V> rightChild = parent.left().right().right(); Node<K, V> leftSubTreeRoot = new BlackNode<>(parent.left().right().getKey(), parent.left().right().getValue(), leftChild, rightChild); Node<K, V> newParent = parent.createNode(parent.getKey(), parent.getValue(), leftSubTreeRoot, this); return this.rebuildsix(newParent, Rotate.R); } else { // rotate Right 修正済み Node<K, V> leftChild = parent.right().left().left(); Node<K, V> rightChild = new RedNode<>(parent.right().getKey(), parent.right().getValue(), parent.right().left().right(), parent.right().right()); Node<K, V> rightSubTreeRoot = new BlackNode<>(parent.right().left().getKey(), parent.right().left().getValue(), leftChild, rightChild); Node<K, V> newParent = parent.createNode(parent.getKey(), parent.getValue(), this, rightSubTreeRoot); return this.rebuildsix(newParent, Rotate.L); } } protected Node<K, V> rebuildsix(Node<K, V> parent, Rotate side) { //case6 if (side == Rotate.L) { // rotate Left Node<K, V> leftChild = parent.right().createNode(parent.getKey(), parent.getValue(), this, parent.right().left()); //check Node<K, V> rightChild = new BlackNode<>(parent.right().right().getKey(), parent.right().right().getValue(), parent.right().right().left(), parent.right().right().right()); return parent.createNode(parent.right().getKey(), parent.right().getValue(), leftChild, rightChild); } else { // rotate Right Node<K, V> leftChild = new BlackNode<>(parent.left().left().getKey(), parent.left().left().getValue(), parent.left().left().left(), parent.left().left().right()); Node<K, V> rightChild = parent.left().createNode(parent.getKey(), parent.getValue(), parent.left().right(), this); return parent.createNode(parent.left().getKey(), parent.left().getValue(), leftChild, rightChild); } } protected abstract boolean isNotEmpty(); public abstract Node<K, V> createNode(K key, V value, Node<K, V> left, Node<K, V> right); abstract Node<K, V> insBalance(); abstract Rotate checkRotate(Rotate side); abstract boolean isRed(); public abstract Node<K, V> replaceNode(Node<K, V> parent, Comparator ctr) throws RotateParent; protected abstract Node deleteNode() throws RotateParent; @Test // test method protected abstract int checkDepth(int count, int minCount); }