1. 程式人生 > 其它 >劍指 Offer 36. 二叉搜尋樹與雙向連結串列(中等)

劍指 Offer 36. 二叉搜尋樹與雙向連結串列(中等)

通過率65.4%

題目連結

題目描述:

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。

為了讓您更好地理解問題,以下面的二叉搜尋樹為例:

我們希望將這個二叉搜尋樹轉化為雙向迴圈連結串列。連結串列中的每個節點都有一個前驅和後繼指標。對於雙向迴圈連結串列,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。

下圖展示了上面的二叉搜尋樹轉化成的連結串列。“head” 表示指向連結串列中有最小元素的節點。

特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回連結串列中的第一個節點的指標。

思路:

深搜,由二叉搜尋樹(左子樹節點都小於根節點,右子樹節點都大於根節點)的特性可知,按中序遍歷二叉樹就能得到一個升序序列,維護前驅節點pre和當前節點cur,有兩個注意點:

  • root為空樹時直接原樣返回
  • pre不能寫在遞迴引數裡,要寫在外面;另外,方便起見,把dfs函式寫在treeToDoublyList()函式裡面,否則寫在外面的話,每次呼叫treeToDoublyList()函式都須先初始化pre和head,否則後一個測試案例的結果會受到前一個測試案例的影響
 1 /*JavaScript*/
 2 /**
 3  * // Definition for a Node.
 4  * function Node(val,left,right) {
5 * this.val = val; 6 * this.left = left; 7 * this.right = right; 8 * }; 9 */ 10 /** 11 * @param {Node} root 12 * @return {Node} 13 */ 14 var treeToDoublyList = function(root) { 15 if(!root) return root 16 17 let head = null 18 let pre = null 19 20 var dfs = function
(cur) { 21 if(!cur) return 22 dfs(cur.left) 23 // 讓head指向連結串列頭節點 24 if(pre) pre.right = cur 25 else head = cur 26 cur.left = pre 27 pre = cur 28 dfs(cur.right) 29 } 30 31 dfs(root) 32 head.left = pre 33 pre.right = head 34 return head 35 };