題目描述:
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
思路一:
按中序遍歷,藉助中間隊列用於存儲樹種的各個節點,然後遍歷隊列,給相鄰節點建立關係;
思路二:
不引入新得變量。只能採用遞歸的方式:
假設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-->