TreeeMap的底层实现

treeMap插入元素的图解法:
插入前:


[img]http://dl.iteye.com/upload/attachment/596734/535868cb-fe05-3cd1-9f9f-a2d876d92b83.gif[/img]

插入过程:
1

[img]http://dl.iteye.com/upload/attachment/596738/bb978c92-5803-350a-b47d-9d974c25cf2d.gif[/img]

2

[img]http://dl.iteye.com/upload/attachment/596740/546a3ddb-324e-3417-8afe-da0a872c213b.gif[/img]

3


[img]http://dl.iteye.com/upload/attachment/596742/bf26905a-bfd0-3b1c-adf0-99b204bca459.gif[/img]


4


[img]http://dl.iteye.com/upload/attachment/596744/385b3ea9-cf6a-3e57-bcc3-1177390afeee.gif[/img]


5


[img]http://dl.iteye.com/upload/attachment/596746/d62058ea-1f09-328d-9028-cc1db5b9f1ae.gif[/img]

6


[img]http://dl.iteye.com/upload/attachment/596748/55dd9b1b-cd37-37d0-a198-100d518648de.gif[/img]

代码分析(转)



public V put(K key, V value)
{
// 先以 t 保存链表的 root 节点
Entry<K,V> t = root;
// 如果 t==null,表明是一个空链表,即该 TreeMap 里没有任何 Entry
if (t == null)
{
// 将新的 key-value 创建一个 Entry,并将该 Entry 作为 root
root = new Entry<K,V>(key, value, null);
// 设置该 Map 集合的 size 为 1,代表包含一个 Entry
size = 1;
// 记录修改次数为 1
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
Comparator<? super K> cpr = comparator;
// 如果比较器 cpr 不为 null,即表明采用定制排序
if (cpr != null)
{
do {
// 使用 parent 上次循环后的 t 所引用的 Entry
parent = t;
// 拿新插入 key 和 t 的 key 进行比较
cmp = cpr.compare(key, t.key);
// 如果新插入的 key 小于 t 的 key,t 等于 t 的左边节点
if (cmp < 0)
t = t.left;
// 如果新插入的 key 大于 t 的 key,t 等于 t 的右边节点
else if (cmp > 0)
t = t.right;
// 如果两个 key 相等,新的 value 覆盖原有的 value,
// 并返回原有的 value
else
return t.setValue(value);
} while (t != null);
}
else
{
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
do {
// 使用 parent 上次循环后的 t 所引用的 Entry
parent = t;
// 拿新插入 key 和 t 的 key 进行比较
cmp = k.compareTo(t.key);
// 如果新插入的 key 小于 t 的 key,t 等于 t 的左边节点
if (cmp < 0)
t = t.left;
// 如果新插入的 key 大于 t 的 key,t 等于 t 的右边节点
else if (cmp > 0)
t = t.right;
// 如果两个 key 相等,新的 value 覆盖原有的 value,
// 并返回原有的 value
else
return t.setValue(value);
} while (t != null);
}
// 将新插入的节点作为 parent 节点的子节点
Entry<K,V> e = new Entry<K,V>(key, value, parent);
// 如果新插入 key 小于 parent 的 key,则 e 作为 parent 的左子节点
if (cmp < 0)
parent.left = e;
// 如果新插入 key 小于 parent 的 key,则 e 作为 parent 的右子节点
else
parent.right = e;
// 修复红黑树
fixAfterInsertion(e); // ①
size++;
modCount++;
return null;
}


排序二叉树:
删除节点元素的时候,需要考虑的因素就比较多了比如删除一个节点后,得考虑这个节点是否有子节点,有几个子节点等等。

一般分为如下几个情况处理。

1):被删除的节点是叶子节点,没关系,不会影响大局,直接删除即可

2):被删节点只有左子树或者只有右子树,被删除的节点只有单子树的。直接将被删节点的子树赋给被删节点的父节点即可,也就是说被删节点的左子树代替被删节点成为被删结点父亲的左子树,而被删节点的右子树代替被删节点成为被删结点父亲的右子树。

3):被删节点既有左子树又有右字数,这种是比较麻烦的,也就是当不当、正不正只删除中间的节点。这个时候就要用被删节点最大左子树的节点或者用最小右子树的的节点代替被删节点。

添加节点:添加节点的过程实际上就是构建排序二叉树的过程。原理如下

1):首先有一个根节点

2):以根节点作为当前节点开始检索

3):新增节点和当前节点进行值比较

4):如果新节点比当前节点大,那么当前节点的右子节点作为新的当前节点,如果当前节点比当前节点小,那么当前节点的左子节点作为新的当前节点。

5):重复3和4步骤直到当前节点没有了子节点,那么新节点作为当前节点的子节点,具体作为左子节点还是有子节点得看新节点的值和当前节点值得比较。

treeMap删除节点的代码分析:

private void deleteEntry(Entry<K,V> p)
{
modCount++;
size--;
// 如果被删除节点的左子树、右子树都不为空
if (p.left != null && p.right != null)
{
// 用 p 节点的中序后继节点代替 p 节点
Entry<K,V> s = successor (p);
p.key = s.key;
p.value = s.value;
p = s;
}
// 如果 p 节点的左节点存在,replacement 代表左节点;否则代表右节点。
Entry<K,V> replacement = (p.left != null ? p.left : p.right);
if (replacement != null)
{
replacement.parent = p.parent;
// 如果 p 没有父节点,则 replacemment 变成父节点
if (p.parent == null)
root = replacement;
// 如果 p 节点是其父节点的左子节点
else if (p == p.parent.left)
p.parent.left = replacement;
// 如果 p 节点是其父节点的右子节点
else
p.parent.right = replacement;
p.left = p.right = p.parent = null;
// 修复红黑树
if (p.color == BLACK)
fixAfterDeletion(replacement); // ①
}
// 如果 p 节点没有父节点
else if (p.parent == null)
{
root = null;
}
else
{
if (p.color == BLACK)
// 修复红黑树
fixAfterDeletion(p); // ②
if (p.parent != null)
{
// 如果 p 是其父节点的左子节点
if (p == p.parent.left)
p.parent.left = null;
// 如果 p 是其父节点的右子节点
else if (p == p.parent.right)
p.parent.right = null;
p.parent = null;
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值