就是最近在做树方面的题时,发现JS和JAVA刷题和C刷题的一个很重要的区别就是传入null的区别
当遍历的时候,C传参数时可以传进去null的指针,因为递归进去,出来时,指针还是指着那个地方
但是JS和JAVA的话,如果传入的不是引用,那么就要通过返回值来记录之前的值,不然的话会丢失之前的状态。
我经常就在null这里犯错误,因为null在C中是null指针,但是在JS和JAVA中null不是引用,仅仅是一种特殊的值。
所以使用JS和JAVA刷关于树递归的题时,最好就是把你要求的值传进去后再返回出来,比如null节点。
比如说拿剑指offer中的26题二叉搜索树与双向链表来说。
我们按照C语言的思想用JS来写就是这样
function Convert(pRootOfTree) {
// write code here
if(pRootOfTree == null) return null;
let pLast=null;
ConvertNode(pRootOfTree,pLast);
let pHead=pLast;
while(pHead&&pHead.left){
pHead=pHead.left;
}
return pHead;
}
function ConvertNode(pNode,pLast){
if(pNode==null) return;
if(pNode.left){
ConvertNode(pNode.left,pLast);
}
pNode.left=pLast;
if(pLast){
pLast.right=pNode;
}
pLast=pNode;
if(pNode.right){
ConvertNode(pNode.right,pLast);
}
}
但是这样无法运行通过,结果为空,为什么呢
这样有一个问题就是如下,当你递归时,到第一层 pLast=null,第二层 pLast=null,到第三层的时候pLast指向了4的那个节点,然后回上去的时候
pLast因为之前第二层是null值,也就是从第二层传进去第三层的时候传的不是地址(只是一个null的值而已),所以从第三层出来第二层的时候,之前的pLast就被清除了,
那么使用的就是第二层的pLast值,也就是此时pLast的值是null.。(可能比较绕口,但是你应该能懂)
好啦渣渣总结完啦,如果你也同时用多种语言的话,希望不要和我踩一样的坑。正确的做法如下
function Convert(pRootOfTree)
{
// write code here
if(pRootOfTree == null) return null;
let pLast=null;
pLast=ConvertNode(pRootOfTree,pLast);
let pHead=pLast;
while(pHead&&pHead.left){
pHead=pHead.left;
}
return pHead;
}
function ConvertNode(pNode,pLast){
if(pNode==null) return;
if(pNode.left){
pLast=ConvertNode(pNode.left,pLast);
}
pNode.left=pLast;
if(pLast){
pLast.right=pNode;
}
pLast=pNode;
if(pNode.right){
pLast=ConvertNode(pNode.right,pLast);
}
return pLast;
}