Mercurial > hg > Members > kazuma > jungle-ormapper
view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/data/treemap/Node.java @ 0:44465893e8b8
first Commit
author | Kazuma |
---|---|
date | Wed, 30 Nov 2016 01:47:55 +0900 |
parents | |
children |
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 rebuildNode delete(K key, Node<K, V> parent, Comparator ctr, Rotate side) { if (this.isNotEmpty()) { rebuildNode 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 { //Equal rebuildNode = replaceNode(parent, ctr); } if (parent == null) return rebuildNode; Node<K, V> node = rebuildNode.getNode(); if (rebuildNode.rebuild()) { return node.deleteBalance(parent, ctr); } Node<K, V> newParent; if (side == Rotate.L) newParent = parent.createNode(parent.getKey(), parent.getValue(), node, parent.right()); else newParent = parent.createNode(parent.getKey(), parent.getValue(), parent.left(), node); return new rebuildNode<>(false, newParent); } return null; } @SuppressWarnings("unchecked") public rebuildNode deleteSubTreeMaxNode(Node<K, V> parent, Comparator ctr, Rotate side) { rebuildNode rebuildNode; Node<K, V> node; if (right().isNotEmpty()) {//最大値のノードが取得できるまで潜る rebuildNode = right().deleteSubTreeMaxNode(this, ctr, Rotate.R); } else { rebuildNode = this.replaceNode(parent, ctr); } if (parent == null) return rebuildNode; if (rebuildNode.rebuild()) { node = rebuildNode.getNode(); return node.deleteBalance(parent, ctr); } if (side == Rotate.R) node = parent.createNode(parent.getKey(), parent.getValue(), parent.left(), rebuildNode.getNode()); else node = parent.createNode(parent.getKey(), parent.getValue(), rebuildNode.getNode(), parent.right()); return new rebuildNode<>(false, node); } public rebuildNode<K, V> deleteBalance(Node<K, V> parent, Comparator ctr) { Node<K, V> newNode = null; 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) { newNode = rebuildThree(parent, Rotate.R); return new rebuildNode<>(true, newNode); } if (rightChild) { newNode = rebuildfive(parent, Rotate.R); return new rebuildNode<>(false, newNode); } else { newNode = rebuildsix(parent, Rotate.R); return new rebuildNode<>(false, newNode); } } else { //左の子が赤 newNode = rebuildTwo(parent, ctr, Rotate.R); return new rebuildNode<>(false, newNode); } } else { //親が赤 if (!rightChild && !leftChild) { newNode = rebuildFour(parent, Rotate.R); return new rebuildNode<>(false, newNode); } if (rightChild) { newNode = rebuildfive(parent, Rotate.R); return new rebuildNode<>(false, newNode); } else { newNode = rebuildsix(parent, Rotate.R); return new rebuildNode<>(false, newNode); } } } else { boolean rightChild = parent.right().right().isRed(); boolean leftChild = parent.right().left().isRed(); if (!parent.isRed()) { //親が黒 if (!parent.right().isRed()) { //左の子が黒 if (!rightChild && !leftChild) { newNode = rebuildThree(parent, Rotate.L); return new rebuildNode<>(true, newNode); } if (rightChild) { newNode = rebuildsix(parent, Rotate.L); return new rebuildNode<>(false, newNode); } else { newNode = rebuildfive(parent, Rotate.L); return new rebuildNode<>(false, newNode); } } else { //左の子が赤 newNode = rebuildTwo(parent, ctr, Rotate.L); return new rebuildNode<>(false, newNode); } } else { //親が赤 if (!rightChild && !leftChild) { newNode = rebuildFour(parent, Rotate.L); return new rebuildNode<>(false, newNode); } if (rightChild) { newNode = rebuildsix(parent, Rotate.L); return new rebuildNode<>(false, newNode); } else { newNode = rebuildfive(parent, Rotate.L); return new rebuildNode<>(false, newNode); } } } } if (0 > (compare(parent.getKey(), ctr))) { newNode = parent.createNode(parent.getKey(), parent.getValue(), parent.left(), this); return new rebuildNode<>(false, newNode); } else { newNode = parent.createNode(parent.getKey(), parent.getValue(), this, parent.right()); return new rebuildNode<>(false, newNode); } } protected Node<K, V> rebuildTwo(Node<K, V> parent, Comparator ctr, Rotate side) { // 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 rebuildNode<K, V> rebuildNode = new rebuildNode<>(false, leftSubTreeRoot); rebuildNode<K, V> leftNodeRebuildNode = this.deleteBalance(rebuildNode.getNode(), ctr); Node<K, V> rightNode = node.right(); return parent.createNode(node.getKey(), node.getValue(), leftNodeRebuildNode.getNode(), rightNode); } else { // rotate Right Node<K, V> node = parent.left(); Node<K, V> rightSubTreeRoot = node.createNode(parent.getKey(), parent.getValue(), node.right(), this); rebuildNode<K, V> rightSubTreeRebuildNode = new rebuildNode<>(false, rightSubTreeRoot); rebuildNode<K, V> rightNodeRebuildNode = this.deleteBalance(rightSubTreeRebuildNode.getNode(), ctr); Node<K, V> leftNode = node.left(); return parent.createNode(node.getKey(), node.getValue(), leftNode, rightNodeRebuildNode.getNode()); } } 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 rebuildNode replaceNode(Node<K, V> parent, Comparator ctr); protected abstract rebuildNode deleteNode(); @Test // test method protected abstract int checkDepth(int count, int minCount); }