Mercurial > hg > Members > tatsuki > TreeMap
view src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/Node.java @ 11:ef442c796b20
change method name exitNode to isNotEmpty and checkColor to isRed
author | tatsuki |
---|---|
date | Fri, 17 Apr 2015 18:06:05 +0900 |
parents | 6304463eefbf |
children | 73e915f29b42 |
line wrap: on
line source
package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; import java.util.*; /** * Created by e115731 on 15/03/23. */ public abstract class Node<K, V> { protected K key; protected V value; protected Node<K, V> right; protected Node<K, V> left; protected boolean rebuildFlag = false; 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 void setRebuildFlag(boolean rebuildFlag){ this.rebuildFlag = rebuildFlag; } public Node<K, V> left() { return left; } public int compare(K parentKey) { return (parentKey.hashCode() - getKey().hashCode()); } public Optional<V> get(K key) { Node<K, V> cur = this; while (cur.isNotEmpty()) { int result = compare(key); 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) { int result = compare(k); if (result > 0) { Node<K, V> node = right.put(k, value); node = createNode(key, this.value, left, node); return node.insBalance(); } else if (result < 0) { Node node = left.put(k, value); return createNode(key, this.value, node, right).insBalance(); } return createNode(key, value, left, right); // equals } public Node<K, V> delete(K key, Node<K, V> parent) { if (this.isNotEmpty()) { int result = compare(key);; if (result > 0) { Node<K, V> node = right.delete(key, this); if (parent == null || node == null) return node; return node.deleteBalance(parent); } else if (result < 0) { Node node = left.delete(key, this); if (parent == null || node == null) return node; return node.deleteBalance(parent); } else if (result == 0) { Node node = replaceNode(parent); // equals if (parent == null || node == null) return node; return node.deleteBalance(parent); } } return null; // no key } public Node<K, V> deleteSubTreeMaxNode(Node<K, V> parent) { Node<K, V> node; if (right().isNotEmpty()) {//最大値のノードが取得できるまで潜る node = right().deleteSubTreeMaxNode(this); if (parent == null) return node; return node.deleteBalance(parent); } node = this.replaceNode(parent); if (parent == null) return node; return node.deleteBalance(parent); } public Node deleteBalance(Node<K, V> parent){ if (rebuildFlag && !isRed()) { if (0 > compare(parent.getKey())) { //自身がどちらの子かを調べる boolean rightChild = parent.left().right().isRed(); boolean leftChild = parent.left().left().isRed(); if (!parent.isRed()) { //親が黒 if (!parent.left().isRed()) { //左の子が黒 if (!rightChild && !leftChild) return rebuildThree(parent, Rotate.R); if (rightChild) return rebuildfive(parent, Rotate.R); else if (leftChild) return rebuildsix(parent, Rotate.R); } else { //左の子が赤 return rebuildTwo(parent, Rotate.R); } } else { //親が赤 if (!rightChild && !leftChild) return rebuildFour(parent, Rotate.R); if (rightChild) return rebuildfive(parent, Rotate.R); else if (leftChild) 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) return rebuildThree(parent, Rotate.L); if (rightChild) return rebuildsix(parent, Rotate.L); else if (leftChild) return rebuildfive(parent, Rotate.L); } else { //左の子が赤 return rebuildTwo(parent, Rotate.L); } } else { //親が赤 if (!rightChild && !leftChild) return rebuildFour(parent, Rotate.L); if (rightChild) return rebuildsix(parent, Rotate.L); else if (leftChild) return rebuildfive(parent, Rotate.L); } } } if (0 > (compare(parent.getKey()))) 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, Rotate side) { // case2 if (side == Rotate.L) { // rotate Left Node<K, V> leftSubTreeRoot = parent.right().createNode(parent.getKey(), parent.getValue(), this, parent.right().left()); // check Node<K, V> leftNode = this.deleteBalance(leftSubTreeRoot); Node<K, V> rightNode = parent.right().right(); return parent.createNode(parent.right().getKey(), parent.right().getValue(), leftNode, rightNode); } else { // rotate Right Node<K, V> rightSubTreeRoot = parent.left().createNode(parent.getKey(), parent.getValue(), parent.left().right(), this); Node<K, V> rightNode = this.deleteBalance(rightSubTreeRoot); Node<K, V> leftNode = parent.left().left(); return parent.createNode(parent.left().getKey(), parent.left().getValue(), leftNode, rightNode); } } protected Node rebuildThree(Node<K, V> parent, Rotate side) { // case3 再起 if (side == Rotate.L) { Node<K, V> rightNode; if (parent.right().isNotEmpty()) rightNode = new RedNode<K, V>(parent.right().getKey(), parent.right().getValue(), parent.right().left(), parent.right().right()); // check else rightNode = new EmptyNode<>(); Node<K, V> newParent = parent.createNode(parent.getKey(), parent.getValue(), this, rightNode); newParent.setRebuildFlag(true); return newParent; } else { Node<K, V> leftNode; if (parent.left().isNotEmpty()) leftNode = new RedNode<K, V>(parent.left().getKey(), parent.left().getValue(), parent.left().left(), parent.left().right()); // check else leftNode = new EmptyNode<>(); Node<K, V> newParent = parent.createNode(parent.getKey(), parent.getValue(), leftNode, this); newParent.setRebuildFlag(true); return newParent; } } protected Node rebuildFour(Node<K, V> parent, Rotate side) { //case 4 if (side == Rotate.R) { Node<K, V> leftNode = new RedNode<K, V>(parent.left().getKey(), parent.left().getValue(), parent.left().left(), parent.left().right()); return new BlackNode<K, V>(parent.getKey(), parent.getValue(), leftNode, this); } else { Node<K, V> rightNode = new RedNode<K, V>(parent.right().getKey(), parent.right().getValue(), parent.right().left(), parent.right().right()); return new BlackNode<K, V>(parent.getKey(), parent.getValue(), this, rightNode); } } protected Node rebuildfive(Node<K, V> parent, Rotate side) { //case5 if (side == Rotate.R) { // rotate Left Node<K, V> leftChild = new RedNode<K, V>(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<K, V>(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<K, V>(parent.right().getKey(), parent.right().getValue(), parent.right().left().right(), parent.right().right()); Node<K, V> rightSubTreeRoot = new BlackNode<K, V>(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 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<K, V>(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<K, V>(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 replaceNode(Node<K, V> parent); protected abstract Node deleteNode(); protected abstract int checkBlackCount(int count); // test method }