27、二叉搜索树与双向链表

来源:互联网 发布:不为谁而作的歌 知乎 编辑:程序博客网 时间:2024/06/08 15:05

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


我的解法

/**public class TreeNode {    int val = 0;    TreeNode left = null;    TreeNode right = null;    public TreeNode(int val) {        this.val = val;    }}*/import java.util.ArrayList;public class Solution {    //public static ArrayList<TreeNode> list = new ArrayList<>();        public TreeNode Convert(TreeNode pRootOfTree) {        if(pRootOfTree == null)            return null;                ArrayList<TreeNode> list = new ArrayList<>();        inTraverse(pRootOfTree, list);                //把list中树节点连接成双向链表        TreeNode last = null;        for(int i = 0; i < list.size() - 1; i ++){            list.get(i).left = last;            list.get(i).right = list.get(i + 1);            last = list.get(i);        }        list.get(list.size() - 1).left = last;        list.get(list.size() - 1).right = null;        list.get(0).left = null;        return list.get(0);           }        //中序遍历,把树的节点按顺序加入list中    public void inTraverse(TreeNode pRootOfTree, ArrayList<TreeNode> list){        if(pRootOfTree == null)            return;        if(pRootOfTree.left != null){            inTraverse(pRootOfTree.left, list);        }        list.add(pRootOfTree);        if(pRootOfTree.right != null){            inTraverse(pRootOfTree.right, list);        }        return;    }    }

算法分析:双链表顺序就是中序顺序。把中序遍历结果按顺序存起来,然后拼接成双链表。 

答案解法

/**public class TreeNode {    int val = 0;    TreeNode left = null;    TreeNode right = null;    public TreeNode(int val) {        this.val = val;    }}*/import java.util.ArrayList;public class Solution {        //开始遍历前,双链表的头部、尾部都为null    TreeNode head = null;    TreeNode tail = null;        //把pRootOfTree转换成双链表,得到了链表头部、尾部,但只返回头部    public TreeNode Convert(TreeNode pRootOfTree) {        if(pRootOfTree == null)            return null;                if(pRootOfTree.left != null){            Convert(pRootOfTree.left);        }                //中序遍历,那么生成头部、尾部的代码肯定在中间部分                //如果链表为null,则head和tail都是pRootOfTree节点        if(tail == null){            head = pRootOfTree;            tail = pRootOfTree;        }else{           //把pRootOfTree加入链表后面,并更新链表尾节点            tail.right = pRootOfTree;            pRootOfTree.left = tail;            tail = pRootOfTree;                  }        if(pRootOfTree.right != null){            Convert(pRootOfTree.right);        }                return head;           }}
算法分析:利用递归,函数的功能就是把树生成双链表。那么把左树生成双链表(只能返回头部),再拼接上root(需要左树的尾部);再把右树生成双链表,再拼接到root后面即可。求左子树尾部是难点,我一开始不知道怎么求,也是因为没想明白它和双向链表的关系。即左子树的头就是双向链表的头,左子树的尾部就是递归到此时双向链表的尾部。那么最开始都为null,则通过递归,头和尾部的初始值最终就会变成最左边的叶子节点,然后设为全局变量。然后return到上一次循环时,链表尾部就是此最左叶节点。接下来只需要进行拼接工作即可。

0 0