JS、JAVA刷题和C刷题的一个很重要的区别
就是最近在做树方面的题时,发现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; }