zoukankan      html  css  js  c++  java
  • 2.看TreeMap源码的deleteEntry方法遇到的问题

    问题场景

            在看TreeMap类是如何删除红黑树时,从remove方法看起,当看到deleteEntry(Entry<K,V> p)方法时:

    就是图中标红的三行代码:

            p.key = s.key;
            p.value = s.value;
            p = s;

            将后继节点的键赋值给待删除节点的键、将后继节点的值赋值给待删除节点的值、将p指向后继节点。

    我的疑惑

            已经将键和值都赋值给待删除的替换节点p了,为什么将p指向s?在这里我我错误的以为p节点指向s节点后,待删除节点的位置就变成s了。其实我这种理解完全错误。

    解决方案

            我产生这样的疑惑,是因为我没有完全理解变量、对象、方法区域;栈、堆之间的关系。在我经过几个小时的小纠结后,我得出的结论如下,用一张图直观的表示出来:

            p是变量,存储在栈中,而通过new创建出来的对象存储在堆中;栈中的变量通过指针指向堆中的对象。p.key = s.key语句将栈中变量指向的对象的key值变成栈中s变量所指向的对象的key值;p.value = s.value语句将栈中p变量所指向的对象的value值变成栈中s变量所指向的对象的value值;之后将栈中p变量指向s所指向的对象。这个解释算是很标准了。

           如果将这个问题放在红黑树中,p为树中一个待删除节点,s为p的后继节点。使用s的key、value值替换p的key和value值,在将p指向s,如果以p为中心的理解,很难理解,是个错误的方向。正确的理解方式:使用栈中s变量所指向的对象的key值和value值赋值给栈中p变量所指向的key值和value值,p所指向的对象是树中要删除被替换掉的节点,使用后继节点替换掉,赋值操作是指上就是在替换节点,而其父节点、左右子树都不用在重新赋值;之后再将栈中p变量指向堆中s之前所指向的对象。p之前所指向的对象在内存的堆中依旧存在,只是不能通过p直接访问了而已。

           在这里要总结一点:java中的变量只是堆中对象的引用,而不是真实的对象本身。变量只是一个对象的引用、变量只是一个对象的引用、变量只是一个对象的引用(重要的事说三遍)。

  • 相关阅读:
    【UOJ #46】 【清华集训2014】玄学
    【BZOJ3626】 [LNOI2014]LCA
    THUSC 2017 游记
    Cqoi2017试题泛做
    全国高校程序设计大赛 评定奖学金
    全国高校程序设计大赛 素数和偶数
    全国高校程序设计大赛 八进制数中含7的总个数
    全国高校程序设计大赛 电商促销
    PTA 02-线性结构1 两个有序链表序列的合并
    PTA 02-线性结构2 一元多项式的乘法与加法运算
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871185.html
Copyright © 2011-2022 走看看