【剑指offer】二叉搜索树与双向链表

61 篇文章 0 订阅
9 篇文章 0 订阅

一、题目描述

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

二、思路分析及代码实现

方法一:

  • 使用链表保存二叉搜索树中序遍历的结果,
  • 通过遍历链表调整二叉搜索树的右子结点为后继节点,左子结点为前驱结点。
  • 注意头结点的前驱结点为null,尾结点的后继结点为null。
import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree==null){
          return pRootOfTree;
        }
      ArrayList<TreeNode> list=new ArrayList<>();
      inorder(pRootOfTree, list);
     return  Convert(list);
    }
  //中序遍历二叉树
  public void inorder(TreeNode pRoot, ArrayList<TreeNode> list){
    if(pRoot!=null){
      inorder(pRoot.left,list);
      list.add(pRoot);
      inorder(pRoot.right,list);
    }
  }
  //根据中序遍历的结果调整节点的顺序
  public TreeNode Convert(ArrayList<TreeNode> list){
    for(int i=0;i<list.size()-1;i++){
      list.get(i).right=list.get(i+1);
      list.get(i+1).left=list.get(i);
    }
    list.get(0).left=null;
    list.get(list.size()-1).right=null;
    return list.get(0);
  }
}

运行时间:

运行时间:22ms
占用内存:8976K

方法二:线索化二叉树

  • 我们设置一个前驱结点,若前驱结点为空,则为头结点,否则,将他的下一个结点的左子节点指向它的前驱结点,前驱结点的右子结点指向当前结点。
  • 该方法其实是不满足题目要求的,因为我们创建了两个新的结点。

代码实现:

public class Solution {
   TreeNode pre=null;
   TreeNode root=null;
   public TreeNode Convert(TreeNode pRootOfTree) {
      if(pRootOfTree==null)
        return null;
      Convert(pRootOfTree.left);
      if(root==null)
        root=pRootOfTree;
      if(pre!=null){
        pRootOfTree.left=pre;
        pre.right=pRootOfTree;
      }
      pre=pRootOfTree;
      Convert(pRootOfTree.right);
      return root;
    }
}

运行时间:

运行时间:22ms
占用内存:9396K

方法三:

public class Solution {
    TreeNode pre=null;
    public TreeNode Convert(TreeNode pRootOfTree) {
        if (pRootOfTree==null)
            return null;
        Convert(pRootOfTree.right);
        if (pre!= null){
            pRootOfTree.right=pre;
            pre.left=pRootOfTree;
        }
        pre=pRootOfTree;
        Convert(pRootOfTree.left);
        return pre;
    }
}

运行时间:

运行时间:18ms
占用内存:9324K

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值