# HG changeset patch # User tatsuki # Date 1427339456 -32400 # Node ID 969798e3d3303c7b98885c6dd21eec3a4ca66d71 # Parent 79ea730fa2f1a0dec54bbdd5fd058adcdc0a9c8e change state pattern diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/BlackNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/BlackNode.java Thu Mar 26 12:10:56 2015 +0900 @@ -0,0 +1,65 @@ +package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; + +import static jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.Rotate.*; + + +public class BlackNode extends Node { + + + public BlackNode(K key, V value, Node left, Node right) { + super(key, value, left, right); + } + + @Override + public Node clone() { + return new BlackNode(key, value, left, right); + } + + @Override + public Node createNode(K key, V value, Node left, Node right) { + return new BlackNode(key, value, left, right); + } + + + @Override + Node balance() { + Rotate spin = left.firstCheckColor(L); + + if (spin == R) { + Node leftChild = new BlackNode(left.left().getKey(), left.left().getValue(), left.left().left(), left.left().right()); + Node rightChild = new BlackNode(getKey(), getValue(), left.right(), right); + return new RedNode(left.getKey(), left.getValue(), leftChild, rightChild); + + } else if (spin == LR) { + Node leftChild = new BlackNode(left.getKey(), left.getValue(), left.left(), left.right().left()); + Node rightChild = new BlackNode(getKey(), getValue(), left.right().right(), right); + return new RedNode(left.right().getKey(), left.right().getValue(), leftChild, rightChild); + + } + + spin = right.firstCheckColor(R); + if (spin == L) { + Node leftChild = new BlackNode(getKey(), getValue(), left, right.left()); + Node rightChild = new BlackNode(right.right().getKey(), (V) right.right().getValue(), right.right().left(), right.right().right()); + return new RedNode(right.getKey(), right.getValue(), leftChild, rightChild); + + } else if (spin == RL) { + Node leftChild = new BlackNode(getKey(), getValue(), left, right.left()); + Node rightChild = new BlackNode(right.right().getKey(), right.right().getValue(), right.right().left(), right.right().right()); + return new RedNode(right.getKey(), right.getValue(), leftChild, rightChild); + + } + + return this; + } + + @Override + Rotate firstCheckColor(Rotate side) { + return N; + } + + @Override + boolean secondCheckColor() { + return false; + } +} diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/EmptyNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/EmptyNode.java Thu Mar 26 12:10:56 2015 +0900 @@ -0,0 +1,50 @@ +package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; + +import java.util.Optional; + +import static jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.Rotate.*; + +/** + * Created by e115731 on 15/03/25. + */ +public class EmptyNode extends Node { + + public EmptyNode() { + super(null, null); + } + + @Override + public Node clone() { + return new EmptyNode(); + } + + @Override + public Node createNode(K key, V value, Node left, Node right) { + return new RedNode(key, value, new EmptyNode(), new EmptyNode()); + } + + @Override + public Node put(Comparable k, V value) { + return new RedNode(k, value, new EmptyNode(), new EmptyNode()); + } + + @Override + Node balance() { + return clone(); + } + + @Override + public Optional get(Comparable key) { + return Optional.ofNullable((V) getValue()); + } + + @Override + Rotate firstCheckColor(Rotate side) { + return N; + } + + @Override + boolean secondCheckColor() { + return false; + } +} diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/Node.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/Node.java Thu Mar 26 12:10:56 2015 +0900 @@ -0,0 +1,85 @@ +package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; + +import java.util.*; + +/** + * Created by e115731 on 15/03/23. + */ +public abstract class Node { + + protected K key; + protected V value; + protected Node right; + protected Node left; + + public Node(K key, V value) { + this.key = key; + this.value = value; + } + + public Node(K key, V value, Node left, Node right) { + this.key = key; + this.value = value; + this.right = right; + this.left = left; + } + + public Node left() { + return left; + } + + public Optional get(Comparable key) { + + int result = key.compareTo(getKey()); + if (result > 0) + return right().get(key); + + else if (result < 0) + return left().get(key); + + else if (result == 0) + return Optional.ofNullable((V) getValue()); + + return Optional.ofNullable(null); + } + + public Node right() { + return right; + } + + public K getKey() { + return key; + } + + public V getValue() { + return value; + } + + + public Node put(Comparable k, V value) { + + int result = k.compareTo(this.key); + + if (result > 0) { + Node node = right.put(k, value); + node = createNode(key, this.value, left, node); + return node.balance(); + } else if (result < 0) { + Node node = left.put(k, value); + return createNode(key, this.value, node, right).balance(); + } + + return createNode(key, value, left, right); // equals + + } + + public abstract Node clone(); + + public abstract Node createNode(K key, V value, Node left, Node right); + + abstract Node balance(); + + abstract Rotate firstCheckColor(Rotate side); + + abstract boolean secondCheckColor(); +} diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/RedNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/RedNode.java Thu Mar 26 12:10:56 2015 +0900 @@ -0,0 +1,61 @@ +package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; + +import static jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.Rotate.*; + +/** + * Created by e115731 on 15/03/25. + */ +public class RedNode extends Node { + + + public RedNode(K key, V value, Node left, Node right) { + super(key, value, left, right); + } + + + @Override + public Node clone() { + return new RedNode(key, value, left, right); + } + + @Override + public Node createNode(K key, V value, Node left, Node right) { + return new RedNode(key, value, left, right); + } + + @Override + protected Node balance() { + return this; + } + + @Override + Rotate firstCheckColor(Rotate side) { + + if (side == L) { + if (left.secondCheckColor()) + return R; + + else if (right.secondCheckColor()) + return LR; + + return N; + } else { + + if (left.secondCheckColor()) + return RL; + + else if (right.secondCheckColor()) + return L; + + return N; + } + + } + + @Override + boolean secondCheckColor() { + return true; + } + + +} diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/Rotate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/Rotate.java Thu Mar 26 12:10:56 2015 +0900 @@ -0,0 +1,8 @@ +package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; + +/** + * Created by e115731 on 15/03/23. + */ +public enum Rotate { + R, L, RL, LR, N; +} diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/TreeMap.java --- a/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/TreeMap.java Tue Mar 24 16:59:09 2015 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/TreeMap/TreeMap.java Thu Mar 26 12:10:56 2015 +0900 @@ -1,46 +1,36 @@ package jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap; +import java.util.Iterator; +import java.util.Optional; + +import static jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.Rotate.*; + /** * Created by e115731 on 15/03/23. */ public class TreeMap { - Entry root; + Node root; int size; - public static void main(String args[]) { - java.util.TreeMap map = new java.util.TreeMap(); - for (int count = 0; count < 100; count++) { - map.put(count, count); - } - } - public TreeMap() { this.root = null; this.size = 0; } - public TreeMap(Entry root, int size) { + + public Node getRoot() { + return root; + } + + public TreeMap(Node root, int size) { this.root = root; this.size = size; } - public V get(K key) { - Entry cur = root; - Comparable k = (Comparable) key; - do { - int result = k.compareTo((K) cur.getKey()); - if (result > 0) - cur = cur.right(); + public Optional get(K key) { + return root.get((Comparable) key); - else if (result < 0) - cur = cur.left(); - - else if (result == 0) - return (V)cur.getValue(); - - }while(cur != null); - return null; } public TreeMap put(K key, V value) { @@ -49,71 +39,33 @@ throw new NullPointerException(); if (isEmpty()) { - Entry newRoot = new Entry(Color.BLACK, key, value); - return new TreeMap(newRoot, size++); + Node newRoot = new BlackNode(key, value, new EmptyNode(), new EmptyNode()); + return new TreeMap(newRoot, size++); } - Comparable k = (Comparable) key; - - Entry newEntry = insert(k, value, root); - Entry root = new Entry(Color.BLACK, newEntry.getKey(), newEntry.getValue(),newEntry.left(),newEntry.right()); - return new TreeMap(root, 0); + Node newEntry = root.put((Comparable) key, value); + Node newRoot = new BlackNode(newEntry.getKey(), newEntry.getValue(), newEntry.left(), newEntry.right()); + return new TreeMap(newRoot, 0); } - private Entry insert(Comparable key, V value, Entry cur) { - int result = key.compareTo((K) cur.getKey()); - - if (result > 0) { - if (cur.right() == null) { - Entry right = new Entry(Color.RED, key, value); - return new Entry(cur.getColor(), cur.getKey(), cur.getValue(), cur.left(), right); - - } - return balance(cur.left(), cur, insert(key, value, cur.right())); - } else if (result < 0) { - if (cur.left() == null) { - Entry left = new Entry(Color.RED, key, value); - return new Entry(cur.getColor(), cur.getKey(), cur.getValue(), left, cur.right()); - - } - return balance(insert(key, value, cur.left()), cur, cur.right()); - - } else // equal - return new Entry(cur.getColor(), key, value, cur.left(), cur.right()); - - } - - private Entry balance(Entry left, Entry cur, Entry right) { - if (cur.getColor() == Color.BLACK && colorRedcheck(left) && colorRedcheck(left.left())) { // rotate right - Entry leftChild = new Entry(Color.BLACK, (K) left.left().getKey(), (V) left.left().getValue(), left.left().left(), left.left().right()); - Entry rightChild = new Entry(Color.BLACK, (K) cur.getKey(), (V) cur.getValue(), left.right(), right); - return new Entry(Color.RED, (K) left.getKey(), (V) left.getValue(), leftChild, rightChild); - - } else if (cur.getColor() == Color.BLACK && colorRedcheck(left) && colorRedcheck(left.right())) { // rotate left right - Entry leftChild = new Entry(Color.BLACK, (K) left.getKey(), (V) left.getValue(), left.left(), left.right().left()); - Entry rightChild = new Entry(Color.BLACK, (K) cur.getKey(), (V) cur.getValue(), left.right().right(), right); - return new Entry(Color.RED, (K) left.right().getKey(), (V) left.right().getValue(), leftChild, rightChild); - - } else if (cur.getColor() == Color.BLACK && colorRedcheck(right) && colorRedcheck(right.left())) { //rotate right left - Entry leftChild = new Entry(Color.BLACK, (K) cur.getKey(), (V) cur.getValue(), left, right.left().left()); - Entry rightChild = new Entry(Color.BLACK, (K) right.getKey(), (V) right.getValue(), right.left().right(), right.right()); - return new Entry(Color.RED, (K) right.left().getKey(), (V) right.left().getValue(), leftChild, rightChild); - - } else if (cur.getColor() == Color.BLACK && colorRedcheck(right) && colorRedcheck(right.right())) { //rotate left - Entry leftChild = new Entry(Color.BLACK, (K) cur.getKey(), (V) cur.getValue(), left, right.left()); - Entry rightChild = new Entry(Color.BLACK, (K) right.right().getKey(), (V) right.right().getValue(), right.right().left(), right.right().right()); - return new Entry(Color.RED, (K) right.getKey(), (V) right.getValue(), leftChild, rightChild); - - } - return new Entry(cur.getColor(),cur.getKey(),cur.getValue(),left,right); - } - - private boolean colorRedcheck(Entry e) { - return e != null && e.getColor() == Color.RED; - } public boolean isEmpty() { return root == null; } + public Iterator keys() { + + return new Iterator() { + + @Override + public boolean hasNext() { + return false; + } + + @Override + public K next() { + return null; + } + }; + } } diff -r 79ea730fa2f1 -r 969798e3d330 src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/test/TreeMapTest.java --- a/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/test/TreeMapTest.java Tue Mar 24 16:59:09 2015 +0900 +++ b/src/main/java/jp/ac/u_ryukyu/ie/cr/tatsuki/test/TreeMapTest.java Thu Mar 26 12:10:56 2015 +0900 @@ -1,18 +1,47 @@ package jp.ac.u_ryukyu.ie.cr.tatsuki.test; +import jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.Node; import jp.ac.u_ryukyu.ie.cr.tatsuki.TreeMap.TreeMap; +import java.util.Optional; + /** * Created by e115731 on 15/03/24. */ public class TreeMapTest { public static void main(String args[]) { TreeMap map = new TreeMap(); - for (int count = 0; count < 1000000; count++) { + TreeMap map1 = map.put(0,0); + TreeMap map2 = map1.put(1,1); + TreeMap map3 = map2.put(2,2); + TreeMap map4 = map3.put(3,3); + TreeMap map5 = map4.put(4,4); + for (int count = 100; count > 0; count--) { map = map.put(count, count); } - System.out.println(map.get(999)); + for (int count = 100; count > -10; count--) { + + Optional op = map.get(count); + if (op.isPresent()) + System.out.println(op.get()); + } + System.out.println("end"); } } + + + + + + + + + + + + + + +