package com.zhuyu_deng.test;
import com.zhuyu_deng.test.MyTreeMap.Entry;
public class MyMap<K, V>
{
// 属性
// root:TreeMap,需要有树根
private Entry<K, V> root;
// currentSize:当前树中结点数
private int currentSize;
// modCount:修改次数;不可并发;
private int modCount;
// 定义常量
private static final boolean BLACK = true;
private static final boolean RED = false;
static class Entry<K, V>
{
// 属性
K key;
V value;
Entry<K, V> left = null;
Entry<K, V> right = null;
Entry<K, V> parent;
boolean color = BLACK;
// 方法
// 新生成的结点都是叶子结点,所有left,right都为NULL;
Entry(K key, V value, Entry<K, V> p)
{
this.key = key;
this.value = value;
parent = p;
}
public K getKey()
{
return key;
}
public V getValue()
{
return value;
}
public V setValue(V newValue)
{
V oldValue = value;
value = newValue;
return oldValue;
}
public int hashCode()
{
return (key == null ? 0 : key.hashCode()) ^ (value == null ? 0 : value.hashCode());
}
public boolean equals(Object o)
{
if (!(o instanceof Entry))
return false;
Entry<K, V> e =(Entry<K, V>) o;
return valEquals(key, e.getKey()) && valEquals(value, e.getValue()); // 对数据的访问尽量用方法,不要直接调用数据(尤其是内部数据)
}
private boolean valEquals(Object o1, Object o2)
{
return (o1 == null ? o2 == null : o1.equals(o2)); // 挺好的这段代码,值得学习。
}
public String toString()
{
return key + " = " + value;
}
}
// 方法
public MyMap()
{
}
public int size()
{
return currentSize;
}
public V get(Object key)
{
Entry<K, V> x = getEntry(key);
return x == null ? null : x.value;
}
// 如果是覆盖,这返回原来的value,否则返回null。
public V put(K key, V value)
{
Entry<K, V> t = root;
if (t == null)
{
root = new Entry<K, V>(key, value, null); // debug了半个小时。
currentSize++;
modCount++;
return null;
}
Entry<K, V> parent;
// 找到需要put的位置
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
int cmp = 0;
do
{
parent = t;
cmp = k.compareTo(parent.key);
if (cmp < 0)
t = parent.left;
else if (cmp > 0)
t = parent.right;
else
{
return t.setValue(value);
}
}while (t != null);
// t指向了null
Entry<K, V> e = new Entry<K, V>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixupAfterInsertion(e);
currentSize++;
modCount++;
return null;
}
// ///
public V remove(Object key)
{
Entry<K, V> x = getEntry(key);
if (x == null)
return null;
V oldValue = x.value;
deleteEntry(x);
return oldValue;
}
// ///
private Entry<K, V> getEntry(Object key)
{
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
Entry<K, V> p = root;
while (p != null)
{
int cmp = k.compareTo(p.key);
if (cmp < 0)
p = p.left;
else if (cmp > 0)
p = p.right;
else
return p;
}
return null;
}
// Insert后只可能破坏:
//
// 1)根节点是黑色的
// 2)红结点有两个黑孩子, x and p[x] 同时为红色,所以while循环的目的就是解决:双红问题,这存在3中情况; 由父亲的兄弟颜色决定,1)红色的兄弟;2)黑色兄弟(黑色兄弟分为两种情况),x在右;3)黑色兄弟,x在左;
// 插入的结点一定是一个叶子结点;可能破坏property:1)根是黑的,2)双红,分别由root.color == BLACK和while循环保持性质。
private void fixupAfterInsertion(Entry<K, V> x)
{
// 默认插入的结点为红色
x.color = RED;
// x是根的时候直接赋值; x不是根,且父亲的颜色为红色的时候才被循环。
while (x != null && x != root && x.parent.color == RED) // 双红
{
// 主要和x的父亲是x的爷爷的左侧还是右侧决定的,主要和x的叔父的颜色有关系(在处理双红问题时)
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) // p[x]为p[p[z]]的左孩子
{
Entry<K, V> y = rightOf(parentOf(parentOf(x)));
if (colorOf(y) == RED)
{
setColor(y, BLACK);
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
x = parentOf(parentOf(x));
}
else
{
if (x == rightOf(parentOf(x)))
{
x = parentOf(x);
rotateLeft(x);
}
else
{
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateRight(parentOf(parentOf(x)));
}
}
}
else
{
Entry<K, V> y = leftOf(parentOf(parentOf(x)));
if (colorOf(y) == RED)
{
setColor(y, BLACK);
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
x = parentOf(parentOf(x));
}
else
{
if (x == leftOf(x))
{
x = parentOf(x);
rotateRight(x);
}
else
{
setColor(parentOf(x), BLACK);
setColor(parentOf(parentOf(x)), RED);
rotateLeft(parentOf(parentOf(x)));
}
}
}
}
root.color = BLACK;
}
// 走到了这一步说明确定要删除一个结点,并且被删除的结点确实存在。
private void deleteEntry(Entry<K, V> x)
{
modCount++;
currentSize--;
// case 1: two children.
if (x.left != null && x.right != null)
{
Entry<K, V> s = successor(x); // leaf or have a child.
x.key = s.key;
x.value = s.value;
x = s; // x always point to the node which will be deleted.
}
// after if implement, x point to the node having no child or one child.
Entry<K, V> replacement = (x.left != null ? x.left : x.right);
if (replacement != null)
{
replacement.parent = x.parent;
if (x.parent == null)
root = replacement;
else if (x == x.parent.left)
x.parent.left = replacement;
else
x.parent.right = replacement;
x.left = x.right = x.parent = null;
if (x.color == BLACK)
fixAfterDeletion(replacement);
}
else if (x.parent == null) // have no children. there is only one node.
{
root = null;
}
else
{
if (x.color == BLACK)
fixAfterDeletion(x);
if (x.parent != null)
{
if (x == x.parent.left)
x.parent.left = null;
else
x.parent.right = null;
}
}
}
// Utilities
private Entry<K, V> parentOf(Entry<K, V> x)
{
return x == null ? null : x.parent;
}
private Entry<K, V> leftOf(Entry<K, V> x)
{
return x == null ? null : x.left;
}
private Entry<K, V> rightOf(Entry<K, V> x)
{
return x == null ? null : x.right;
}
private boolean colorOf(Entry<K, V> x)
{
return x == null ? BLACK : x.color;
}
private void setColor(Entry<K, V> x, boolean c)
{
if (x != null)
x.color = c;
}
private void rotateLeft(Entry<K, V> x)
{
if (x != null)
{
Entry<K, V> r = rightOf(x);
x.right = r.left;
if (r.left != null)
r.left.parent = x;
r.parent = x.parent;
if (x.parent == null)
root = r;
else
{
if (x == leftOf(x))
x.parent.left = r;
else
x.parent.right = r;
}
x.parent = r;
r.left = x;
}
}
private void rotateRight(Entry<K, V> x)
{
if (x != null)
{
Entry<K, V> lt = x.left;
x.left = lt.right;
if (lt.right != null)
lt.right.parent = x;
lt.parent = x.parent;
if (x.parent == null)
root = x;
else
{
if (x == parentOf(x))
x.parent.left = lt;
else
x.parent.right = lt;
}
x.parent = lt;
lt.right = x;
}
}
private Entry<K, V> successor(Entry<K, V> x)
{
// case 1
if (x == null)
return null;
// case 2
else if (x.right != null)
{
Entry<K, V> t = x.right;
while (t.left != null)
{
t = t.left;
}
return t;
}
// case 3
// d
// c
// b
// a <- x
//
else
{
Entry<K, V> p = x.parent;
Entry<K, V> ch = x;
while (p != null && ch == p.right)
{
ch = p;
p = p.parent;
}
return p;
}
}
// x 指向被赋予了一层黑色的结点。
private void fixAfterDeletion(Entry<K, V> x)
{
// x 是指向被赋予了一层黑色的结点,while循环(当x双重黑色的时候)
while (x != root && colorOf(x) == BLACK) // when x is root, make it BLACK directly.
{
if (x == leftOf(parentOf(x)))
{
Entry<K, V> sib = rightOf(parentOf(x));
if (colorOf(sib) == RED)
{
setColor(parentOf(x), RED);
setColor(sib, BLACK);
rotateLeft(parentOf(x));
sib = rightOf(parentOf(x)); // 记住每次都要重新置兄弟值。
}
else if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(x)) == BLACK)
{
setColor(sib, RED);
x = parentOf(x);
}else
{
// 要这样写代码,因为case3之后,可能进入case4;
if (colorOf(rightOf(sib)) == BLACK)
{
setColor(sib, RED);
setColor(leftOf(sib), BLACK);
rotateRight(sib);
sib = rightOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
setColor(rightOf(sib), BLACK);
rotateLeft(parentOf(x));
x = root;
}
}
else
{
Entry<K, V> sib = leftOf(parentOf(x)); // 删除后的4种情况,由x的兄弟决定的。
if (colorOf(sib) == RED)
{
setColor(parentOf(x), RED);
setColor(sib, BLACK);
rotateRight(parentOf(x));
sib = leftOf(parentOf(x));
}
else if (colorOf(leftOf(sib)) == BLACK && colorOf(rightOf(sib)) == BLACK)
{
setColor(sib, RED);
x = parentOf(x);
}
else
{
if (colorOf(leftOf(sib)) == BLACK)
{
setColor(sib, RED);
setColor(rightOf(sib), BLACK);
rotateLeft(sib);
sib = leftOf(parentOf(x));
}
setColor(sib, colorOf(parentOf(x)));
setColor(parentOf(x), BLACK);
rotateRight(parentOf(x));
x = root;
}
}
}
// x 原来是红色的,直接红色就可以了。
setColor(x, BLACK);
}
}
MyMap
最新推荐文章于 2022-08-10 11:34:29 发布