MyMap

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);
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值