題目
輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
我的思路
一開始並沒有理解題目中,不能創建任何新節點的意思,還以為是不能定義任何變量呢,后面看了評論才知道原來是不能使用new來創建節點。總的來說,用中序遍歷可以較容易的解決這個問題。
沒有定義任何變量版
思路不復雜,只不過在處理上有點繁瑣。總的來說就是先遞歸找到最小的三個節點,然后修改它們之間的左右關系。再返回到上一級,再確定它們之間的左右關系,如此如此這般這般......就可以了。
public TreeNode Convert(TreeNode pRootOfTree) {
if (pRootOfTree == null) return null;
if (pRootOfTree.left != null) {
if (pRootOfTree.left.left == null && pRootOfTree.left.right == null)
pRootOfTree.left.right = pRootOfTree;
else {
Convert(pRootOfTree.left);
if (pRootOfTree.left.right != null)
pRootOfTree.left = pRootOfTree.left.right;
pRootOfTree.left.right = pRootOfTree;
}
}
if (pRootOfTree.right != null) {
if (pRootOfTree.right.left == null && pRootOfTree.right.right == null)
pRootOfTree.right.left = pRootOfTree;
else {
Convert(pRootOfTree.right);
if (pRootOfTree.right.left != null)
pRootOfTree.right = pRootOfTree.right.left;
pRootOfTree.right.left = pRootOfTree;
}
}
return findLeft(pRootOfTree);
}
//為了找到鏈表的頭結點
private TreeNode findLeft(TreeNode root) {
while (root.left != null)
root = root.left;
return root;
}
中序遍歷,簡單清晰版
定義兩個分別指向鏈表最左端和最右端的變量(或者說指針)。然后在中序遍歷中不斷的修改節點之間的指針指向,右指針不斷的右移動,直到遍歷結束。
private TreeNode leftHead = null;
private TreeNode rightHead = null;
public TreeNode Convert(TreeNode pRootOfTree) {
if (pRootOfTree == null) return null;
Convert(pRootOfTree.left);
if (leftHead == null) {
leftHead = pRootOfTree;
rightHead = pRootOfTree;
}
else {
rightHead.right = pRootOfTree;
pRootOfTree.left = rightHead;
rightHead = pRootOfTree;
}
Convert(pRootOfTree.right);
return leftHead;
}