剑指offer_二叉搜索树与双向链表JAVA

题目:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。


1.思路:目标是将二叉搜索树变成有序的双向链表,可以这么做:
    第一步:首先将二叉搜索树按中序遍历,然后存入ArrayList中
    第二步:将arraylist中前后节点用指针串起来,left指针指向前一个,right指针指向后一个,首元素的left为null,尾元素的right为null
    如果将二叉搜索树的每个节点看成一个个小珠子,那么第一步就是将这些小珠子按顺序放入槽中,第二步就是用线将这些珠子串起来
2.二叉搜索树的中序遍历得到的结果刚好是从小到大排序的
3.再理一下非递归中序遍历的思路:
list中保存的是最后的便利结果
1)首先是沿着根节点向左走,一直左走,直到左孩子为空(不一定为叶子,因为有可能最后一个双亲节点没有左孩子,只有右孩子),这时候栈里的就是根节点到左孩子为空的路径
(地点2),然后就应该出栈对吧(地点3),出栈就意味着遍历过了,以后不再访问了,那么就加入list中(地点4),然后到达地点5,这时候就有两种情况了:
      第一种:如果地点4中已经遍历的是叶子节点,那么就意味着下一个遍历节点应该是它的父亲节点,那么,就不应该走地点2那个循环,如果再走2那个循环,这样不就
             死循环了吗,所以我们将tmp置为null
      第二种:如果地点4出现的是双亲节点,此时左子树和自己本身已经遍历过了,那么如果有右子树,就应该开始遍历右子树,将tmp置为tmp.right
2)关于开始的时候while(!stack.empty()||(tmp!=null))这个里面为什么这么写呢,这些可以不用刻意去记,你想啊,开始stack为空,那么想要进循环那么就要加一个tmp不为空。

importjava.util.*;
publicclassSolution {
    public  TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null)returnpRootOfTree;
        if(pRootOfTree.left==null&& pRootOfTree.right==null)returnpRootOfTree;
        ArrayList<TreeNode>list1=newArrayList<TreeNode>();// 用来装搜索二叉树的中序遍历
        Stack<TreeNode>stack=newStack<TreeNode>();// 栈,非递归中序遍历需要栈的辅助
        TreeNode root=pRootOfTree;
         
        // 非递归中序遍历
        TreeNode tmp=root;
        while(!stack.empty()||(tmp!=null)) {//地点1
            while(tmp!=null) {
                stack.push(tmp);
                tmp=tmp.left;
            }//地点2
            tmp=stack.pop();//地点3
            list1.add(tmp);//地点4
            if(tmp.right!=null) {//地点5,如果是有右子树,那么就遍历右子树
                tmp=tmp.right;
            }
            elsetmp=null;
        }
        // 然后将这些节点按顺序串起来
        inti;
        for(i=0;i<list1.size()-1;i++) {// 因为后面一次循环是取相邻两个节点出来,所以范围是i<list1.size()-1
            if(i==0)list1.get(i).left=null;
            list1.get(i).right=list1.get(i+1);
            list1.get(i+1).left=list1.get(i);
        }
        list1.get(i).right=null;
        returnlist1.get(0);
    }
}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值