题目描述
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路
- 先搞定右边的,将右子树转化为链表,并使用prev保存头结点。
- 将根节点的右指针指向prev,prev的左指针指向根节点,这样头结点和右子树就转化成功了。
- 使prev指向根节点,这样就获得了根节点和右子树所组成链表的头结点
- 处理左子树
总之就是讲右子树转化的列表串到左子树的后边,示意图如下
优点:在合并的时候不需要利用循环查询尾节点,并且实现起来只要十行代码,所以我觉得很优雅:)
5
/ \
3 6
/ \
2 4
==>
3
/ \
2 4 prev = 5->6
=>
递归到节点4的时候
3
/ \
2 4
\
5
\
6
然后
2 ,prev=3->4->5->6
最后 2->3->4->5->6
public class Solution {
//定义节点
public static class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
// 用于保存右子树及头结点组成的链表的头指针
private TreeNode prev;
// 转化函数
public TreeNode Convert(TreeNode root) {
if(root == null)
return null;
Convert(root.right);
root.right = prev;
if(prev != null)
prev.left = root;
prev = root;
if(root.left != null)
return Convert(root.left);
return root;
}
//测试
public static void main(String[] args) {
TreeNode root = new TreeNode(10);
root.left = new TreeNode(6);
root.right = new TreeNode(14);
root.left.left = new TreeNode(4);
root.left.right = new TreeNode(8);
root.right.left = new TreeNode(12);
root.right.right = new TreeNode(16);
root.left.right = new TreeNode(4);
Solution s = new Solution();
TreeNode x = s.Convert(root);
while (x.right!= null){
System.out.println(x.val);
x = x.right;
}
System.out.println(x.val);
System.out.println("---");
while (x != null){
System.out.println(x.val);
x = x.left;
}
}
}