剑指offer:将一棵二叉搜索树转化为双向链表

题目叙述

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

方法一:

  1. 先对二叉树进行中序遍历并且将其遍历的所有结点进行保存
  2. 遍历保存好的中序遍历序列然后进行修改其左右指向,这里需要注意的是第一个结点和尾结点需要单独处理。对于双向链表来说,第一个结点没有前指向,认为指向为空,尾结点没有后指向,认为指向为空。
import java.util.ArrayList;
//import java.util.List;
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
       //首先得是中序遍历
       //使用一个arraylist进行保存中序遍历的节点
        if (pRootOfTree==null) return null;
        if (pRootOfTree.left == null && pRootOfTree.right==null) return pRootOfTree;
        ArrayList<TreeNode> lis  = new  ArrayList<>();
        TraverseMid(pRootOfTree, lis);
        //处理第一个节点,它只有右孩子指向
        lis.get(0).right = lis.get(1);
        //处理中间的节点
        for(int i=1;i<lis.size()-1;i++){
            lis.get(i).left = lis.get(i-1);
            lis.get(i).right = lis.get(i+1);
        }
        //处理最后一个节点,它只有左孩子指向
        lis.get(lis.size()-1).left = lis.get(lis.size()-2);
        return lis.get(0);
        
    }
    public void TraverseMid(TreeNode pRootOfTree, ArrayList lis){
        if(pRootOfTree == null) return;
        TraverseMid(pRootOfTree.left, lis);
        lis.add(pRootOfTree);
        TraverseMid(pRootOfTree.right, lis);
    }
}

方法二:

参考:主要是采用递归的思想,左右子树分别考虑然后再拼接,中间连接结点是原始二叉搜索数的根节点。主要思想还是,对于二叉搜索树来说,最左边的节点就是最小元素节点,最右边的节点就是最大元素节点。
链接:https://www.nowcoder.com/questionTerminal/947f6eb80d944a84850b0538bf0ec3a5?f=discussion
来源:牛客网
1.将左子树构造成双链表,并返回链表头节点。
2.定位至左子树双链表最后一个节点。
3.如果左子树链表不为空的话,将当前root追加到左子树链表。
4.将右子树构造成双链表,并返回链表头节点。
5.如果右子树链表不为空的话,将该链表追加到root节点之后。
6.根据左子树链表是否为空确定返回的节点。

public TreeNode Convert(TreeNode root) {
        if(root==null)
            return null;
        if(root.left==null&&root.right==null)
            return root;
        // 1.将左子树构造成双链表,并返回链表头节点
        TreeNode left = Convert(root.left);
        TreeNode p = left;
        // 2.定位至左子树双链表最后一个节点
        while(p!=null&&p.right!=null){
            p = p.right;
        }
        // 3.如果左子树链表不为空的话,将当前root追加到左子树链表
        if(left!=null){
            p.right = root;
            root.left = p;
        }
        // 4.将右子树构造成双链表,并返回链表头节点
        TreeNode right = Convert(root.right);
        // 5.如果右子树链表不为空的话,将该链表追加到root节点之后
        if(right!=null){
            right.left = root;
            root.right = right;
        }
        return left!=null?left:root;       
    }
发布了126 篇原创文章 · 获赞 5 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zhpf225/article/details/103398739