题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
思路一:
按中序遍历,借助中间队列用于存储树种的各个节点,然后遍历队列,给相邻节点建立关系;
思路二:
不引入新得变量。只能采用递归的方式:
假设root节点的左右子树已经是双向链表,那么只用将root和左右子树对应链表的最大值和最小值建立连接;
示例代码:
public class Main {
public static void main(String args[]) {
TreeNode node1 = new TreeNode(1), node2 = new TreeNode(2), node3 = new TreeNode(3), node4 = new TreeNode(4);
node2.left = node1;
node2.right = node3;
node3.right = node4;
TreeNode head = Convert(node2);
while (head != null) {
System.out.print(head.val + "-->");
head = head.right;
}
}
public static TreeNode Convert(TreeNode r) {
if (r == null)
return null;
if (r.left != null) {
r.left = midTraverseLeft(r.left);
r.left.right = r;
}
if (r.right != null) {
r.right = midTraverseRight(r.right);
r.right.left = r;
}
while (r.left != null)
r = r.left;
return r;
}
public static TreeNode midTraverseLeft(TreeNode r) {
if (r == null)
return null;
if (r.left != null)
midTraverseLeft(r.left).right = r;
if (r.right != null)
midTraverseRight(r.right).left = r;
if (r.right != null)
return r.right;
return r;
}
public static TreeNode midTraverseRight(TreeNode r) {
if (r == null)
return null;
if (r.left != null)
midTraverseLeft(r.left).right = r;
if (r.right != null)
midTraverseRight(r.right).left = r;
if (r.left != null)
return r.left;
return r;
}
}
输出结果:
1-->2-->3-->4-->
递归改进:
从上述代码中可以看到,代码相似度很高,可以减少代码量(但是源代码更容易理解)。每个root和root.right的情形一模一样,与root.left不一样。root要返回最小值(最左边的节点),root.left要返回最大值(最右边的节点)。因此,midTraverseRight可以用Convert代替。
代码如下:
public class Main {
public static void main(String args[]) {
TreeNode node1 = new TreeNode(1), node2 = new TreeNode(2), node3 = new TreeNode(3), node4 = new TreeNode(4);
node2.left = node1;
node2.right = node3;
node3.right = node4;
TreeNode head = Convert(node2);
while (head != null) {
System.out.print(head.val + "-->");
head = head.right;
}
}
public static TreeNode Convert(TreeNode r) {
if (r == null)
return null;
if (r.left != null) {
r.left = midTraverseLeft(r.left);
r.left.right = r;
}
if (r.right != null) {
r.right = Convert(r.right);
r.right.left = r;
}
while (r.left != null)
r = r.left;
return r;
}
public static TreeNode midTraverseLeft(TreeNode r) {
if (r == null)
return null;
if (r.left != null)
midTraverseLeft(r.left).right = r;
if (r.right != null)
Convert(r.right).left = r;
if (r.right != null)
return r.right;
return r;
}
}
输出结果:
1-->2-->3-->4-->