从二叉搜索树的第k个节点问题看递归如何返回普通变量和对象

来源:互联网 发布:淘宝鳄鱼皮真假鉴别 编辑:程序博客网 时间:2024/06/06 12:54

      在剑指offer有个求“二叉搜索树的第k个节点(从小到大)”问题。利用BST的性质,直接递归中序遍历即可。但是得到的结果总是null。例图如下:

     

      原来的代码如下:

public class Test {    TreeNode KthNode(TreeNode pRoot, int k)     { if(pRoot==null || k<=0)  return null; int[] array=new int[2]; array[0]=k; TreeNode ansNode=null;     return findKth(pRoot,array);     }TreeNode findKth(TreeNode pRoot, int[] array) {if(pRoot==null )return null;findKth(pRoot.left,array);array[1]++;if(array[0]==array[1]) return pRoot; findKth(pRoot.right,array);return null;}public static void main(String[] args){TreeNode node5=new TreeNode(5);TreeNode node3=new TreeNode(3);TreeNode node7=new TreeNode(7);TreeNode node2=new TreeNode(2);TreeNode node4=new TreeNode(4);TreeNode node6=new TreeNode(6);TreeNode node8=new TreeNode(8);    node5.left= node3;    node5.right=node7;       node3.left= node2;    node3.right=node4 ;       node7.left=node6 ;    node7.right= node8;         node2.left= null;    node2.right=null;       node4.left= null;    node4.right=null;      node6.left= null;    node6.right=null ;     node8.left= null;    node8.right=null;         System.out.println(new Test().KthNode(node5, 1).val); }}


      这么简洁的代码,最后得到结果却不对。如果用它输出在判断相等的时候直接输出是可以的,但是让它返回就出错。我们分析一下过程,进栈顺序:5-3-2,在2确认2最小后,return pRoot,但是,往下还是要到3和4,即3-4-5-6-7-8,最后访问8的右子树,输出结果肯定是null。是否可以改变递归终止的条件限定呢,比如在找到第k个值后,令array[1]>array[0],开始判断出array[1]>array[0],就返回,但是这样也只能返回null。是否可以用一个空节点变量作为递归参数值,当找到时,将这个节点赋给这个节点变量呢?不行,因为递归是由栈实现的,首先保护现场,然后往下调用,现场保护的节点变量为null,递归回来恢复现场时,仍然是null。

    在上面的程序中,可以看到,节点从小到大计数变量是存在一个数组中,这样在某一子递归改变计数变量值,返回到递归中时,仍然保留了改变后的值。其实对对象的修改都可以保留。但是本问题中,查到的对象已经存在,因此不是修改对象的问题。可以考虑建立一个只有元素的节点数组作为参数。这时,对数组元素的修改将一直存在。其实,只要找到第k大元素,从现有的栈返回即可,不需要继续加深栈的深度,所以当nodeArray[0]!=null时,直接返回;具体完整实现如下:

public class Demo { TreeNode KthNode(TreeNode pRoot, int k)     { if(pRoot==null || k<=0)  return null; int[] array=new int[2]; array[0]=k; TreeNode[] nodeArray=new TreeNode[1];   findKth(pRoot,array,nodeArray);   return nodeArray[0];    }TreeNode findKth(TreeNode pRoot, int[] array, TreeNode[] nodeArray) {if(pRoot==null || nodeArray[0]!=null)return null;findKth(pRoot.left,array,nodeArray);array[1]++;if(array[0]==array[1]) nodeArray[0]=pRoot; findKth(pRoot.right,array,nodeArray);return null;}public static void main(String[] args){TreeNode node5=new TreeNode(5);TreeNode node3=new TreeNode(3);TreeNode node7=new TreeNode(7);TreeNode node2=new TreeNode(2);TreeNode node4=new TreeNode(4);TreeNode node6=new TreeNode(6);TreeNode node8=new TreeNode(8);    node5.left= node3;    node5.right=node7;       node3.left= node2;    node3.right=node4 ;       node7.left=node6 ;    node7.right= node8;         node2.left= null;    node2.right=null;       node4.left= null;    node4.right=null;      node6.left= null;    node6.right=null ;     node8.left= null;    node8.right=null;         System.out.println(new Demo().KthNode(node5, 1).val); }}




    

       

原创粉丝点击