二叉搜索树与双向链表

二叉搜索树转排序链表

1、题目

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

2、解法

1、递归法

import java.util.ArrayList;
public class Solution {
    public ArrayList<TreeNode> arr = new ArrayList<>();
    public TreeNode Convert(TreeNode pRootOfTree) {
        Inorder(pRootOfTree);
        // 如果是1个结点或者没有,直接输出
        if(arr.size() == 1 || arr.size() == 0)
            return pRootOfTree;
        TreeNode root = null;
        // 使用pre作为中间结点
        TreeNode pre = null;
        TreeNode node = null;
        for(int i=0; i<arr.size()-1 ; i++){
            if(i==0){
                root = arr.get(i);
                root.left = pre;
                pre = root;
                root.right = arr.get(i+1); 
            }else{
                node = arr.get(i);
                node.left = pre;
                pre = node;
                node.right = arr.get(i+1);
            } 
        }
        node = arr.get(arr.size()-1);
        node.left = pre;
        node.right = null;
        return root;
    }
    //中序遍历
  public void Inorder(TreeNode t){
      if (t == null) return;
      Inorder(t.left);
      if(t != null)
          arr.add(t);
      Inorder(t.right);
     }
}

时间复杂度为O(n)
空间复杂度为O(n)

2、使用栈

import java.util.LinkedList;
import java.util.Stack;
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
    if (pRootOfTree == null) {
                return null;
     }
     return convert(pRootOfTree); 
    }

    public TreeNode convert(TreeNode root){
        Stack<TreeNode> stack = new Stack<>();
        LinkedList<TreeNode> queue = new LinkedList<>();
        TreeNode node = root;  

        while(node != null || !stack.isEmpty()){
            // 一路走到最左边
            while(node != null){ 
                stack.push(node);
                node = node.left; 
            }
            // 栈是否为空
            if(!stack.isEmpty()){
                // 判断的时候,只要看一课树就可以
                // 左边结束,根出去,再看右边
                node = stack.pop();
                queue.offer(node);
                node = node.right;
            }
        }
        // 对队列当中的结点修改左右结点
        for(int i = 0; i < queue.size(); i++){
            // 从右往左执行
            TreeNode left = i == 0 ? null : queue.get(i - 1);
            TreeNode right = i == queue.size()-1 ? null : queue.get(i+1);
            queue.get(i).left = left;
            queue.get(i).right = right;
        }
        return queue.get(0);
    }
}

时间复杂度为O(n)
空间复杂度为O(n)
用双向链表的get实际上是很慢的,所以这里采用ArrayList比较好

3、一些概念

3.1 二叉搜索树的前驱和后继

前驱(比它小的结点关键字中的最大值 )
结点的左子树结点的左父母结点的右父母的左父母(或往上找左父母)
后继(比它大的结点关键字中的最小值 )
结点的右子树结点的右父母结点的左父母的右父母(或往上找右父母)

链接

3.2 二叉搜索树的插入、删除和其他知识

链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值