劍指Offer-26.二叉搜尋樹與雙向連結串列(Javascript)
阿新 • • 發佈:2018-12-16
26.二叉搜尋樹與雙向連結串列
題目描述
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
解題思路
-
因為要對二叉搜尋樹重新排序為雙向連結串列,因此可以看出此題應當用中序遍歷,看到樹的題目,基本要想到遞迴和前中後序遍歷。
-
兩種解題思路,均基於遞迴。
-
這裡要注意:C++的指標類解法不能直接用於js,因為js的非基本資料型別的傳遞問題~ 可能會出錯~
Code
- 解法一: 基礎的遞迴
- 構建左子樹為雙向連結串列,返回連結串列頭節點left
- 定位到左雙向連結串列最後一個節點
- 左雙向連結串列最後一個節點與當前節點雙向連結
- 構建右子樹為雙向連結串列,返回連結串列頭結點right
- 將右雙向連結串列頭節點和當前節點連線起來
- 返回雙向連結串列最左邊的頭節點(即:有left為left,無left為根節點root)
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
function Convert(root)
{
// write code here
if(!root) return null;
if(!root.left && !root.right) return root;
//構建左子樹為雙向連結串列,返回連結串列頭節點left
var left = Convert(root.left);
var tmp = left;
//若左子樹存在,則用tmp定位到左雙向連結串列最後一個節點
while(tmp && tmp.right){
tmp = tmp.right;
}
//若左子樹存在,將左雙向連結串列最後一個節點和當前節點連線起來
//注意這裡,tmp與left的存在與否完全相同
if(tmp){
tmp.right = root;
root.left = tmp;
}
//構建右子樹為雙向連結串列,返回連結串列頭結點right
var right = Convert(root.right);
//將右雙向連結串列頭節點和當前節點連線起來
if(right){
right.left = root;
root.right = right;
}
//若有左子樹,返回的永遠是最左邊的葉子節點(也就是最小的節點),若無左子樹,則根節點就是最小的節點
return left?left:root;
}
- 解法二: 使用全域性變數leftLast來表示左雙向連結串列的最後一個節點(也就是上一種解法中的tmp)
/* function TreeNode(x) {
this.val = x;
this.left = null;
this.right = null;
} */
var leftLast;
function Convert(root)
{
// write code here
if(!root){
return null;
}
//返回最左邊的頭節點,並且此時左雙向連結串列的最後一個節點也是該節點
if(root == null && root == null){
leftLast = root;
return root;
}
//構建左子樹為雙向連結串列,返回連結串列頭節點left
var left = Convert(root.left);
//若左子樹存在,則將左雙向連結串列最後一個節點與當前節點連線起來
//這裡,leftLast和left的存在與否並不完全一致哦!
if(left){
leftLast.right = root;
root.left = leftLast;
}
//那麼此時不論有沒有left,左雙向連結串列的最後一個節點都是當前root啦
leftLast = root;
//構建右子樹為雙向連結串列,返回連結串列頭結點right
var right = Convert(root.right);
//將右雙向連結串列頭節點和當前節點連線起來
if(right){
right.left = root;
root.right = right;
}
//若有左子樹,返回的永遠是最左邊的葉子節點(也就是最小的節點),若無左子樹,則根節點就是最小的節點
return left?left:root;
}