二叉查找树变为有序的双向链表


将二叉查找树变为有序的双向链表 要求不能创建新节点,只调整指针。


/** 
     * 
     * 递归解法: 
     * 参考了http://stackoverflow.com/questions/11511898/converting-a-binary-search-tree-to-doubly-linked-list#answer-11530016 
     * 感觉是最清晰的递归解法,但要注意递归完,root会在链表的中间位置,因此要手动 
     * 把root移到链表头或链表尾 
     */  
    public static TreeNode convertBST2DLLRec(TreeNode root) {  
        root = convertBST2DLLSubRec(root);  
          
        // root会在链表的中间位置,因此要手动把root移到链表头  
        while(root.left != null){  
            root = root.left;  
        }  
        return root;  
    }  
      
    /** 
     *  递归转换BST为双向链表(DLL) 
     */  
    public static TreeNode convertBST2DLLSubRec(TreeNode root){  
        if(root==null || (root.left==null && root.right==null)){  
            return root;  
        }  
          
        TreeNode tmp = null;  
        if(root.left != null){          // 处理左子树  
            tmp = convertBST2DLLSubRec(root.left);  
            while(tmp.right != null){   // 寻找最右节点  
                tmp = tmp.right;  
            }  
            tmp.right = root;       // 把左子树处理后结果和root连接  
            root.left = tmp;  
        }  
        if(root.right != null){     // 处理右子树  
            tmp = convertBST2DLLSubRec(root.right);  
            while(tmp.left != null){    // 寻找最左节点  
                tmp = tmp.left;  
            }  
            tmp.left = root;        // 把右子树处理后结果和root连接  
            root.right = tmp;  
        }  
        return root;  
    } 
    /** 
     * 将二叉查找树变为有序的双向链表 迭代解法 
//   * 类似inorder traversal的做法 
     */  
    public static TreeNode convertBST2DLL(TreeNode root) {  
        if(root == null){  
            return null;  
        }  
        Stack<TreeNode> stack = new Stack<TreeNode>();  
        TreeNode cur = root;        // 指向当前处理节点  
        TreeNode old = null;            // 指向前一个处理的节点  
        TreeNode head = null;       // 链表头  
          
        while( true ){  
            while(cur != null){     // 先添加一个非空节点所有的左孩子到栈  
                stack.push(cur);  
                cur = cur.left;  
            }  
              
            if(stack.isEmpty()){  
                break;  
            }  
                  
            // 因为此时已经没有左孩子了,所以输出栈顶元素  
            cur = stack.pop();  
            if(old != null){  
                old.right = cur;  
            }  
            if(head == null){       // /第一个节点为双向链表头节点  
                head = cur;  
            }  
              
            old = cur;          // 更新old  
            cur = cur.right;    // 准备处理右子树  
        }  
          
        return head;  
    } 





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值