劍指Offer 36.二叉搜尋樹與雙向連結串列
阿新 • • 發佈:2020-10-10
劍指Offer 36.二叉搜尋樹與雙向連結串列
題目
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。
為了讓您更好地理解問題,以下面的二叉搜尋樹為例:
我們希望將這個二叉搜尋樹轉化為雙向迴圈連結串列。連結串列中的每個節點都有一個前驅和後繼指標。對於雙向迴圈連結串列,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。
下圖展示了上面的二叉搜尋樹轉化成的連結串列。“head” 表示指向連結串列中有最小元素的節點。
特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回連結串列中的第一個節點的指標。
解析
最開始我是使用的佇列+中序遍歷
的方式來完成二叉搜尋樹轉換為雙向連結串列。這個方式雖然可以完成操作,但是時間複雜度很低,擊敗了16.68%的使用者。哈哈哈。
後來,直接用中序遍歷+pre指標+cur指標
來完成轉換。因為直接用遍歷轉換,所以效率比較高。擊敗了100%
解釋一下,思路:
利用pre
、cur
指標。pre
指標是記錄前一個節點,cur
指標是記錄當前節點。head
指標是記錄頭節點,即第一個節點,方便形成環狀。
還是利用中序遍歷。在操作的時候分兩種情況:
pre
為null,則表示cur
指標指向的是第一個節點,此時就應該將head
指標指向第一個節點,記錄下來。pre
不為null,則表示有前驅節點,直接按照雙向連結串列規則,確定前驅和後繼指標。然後將pre
cur
,確定下一個前驅節點。
最佳理解為:畫圖。哈哈哈
解答
/* // Definition for a Node. class Node { public int val; public Node left; public Node right; public Node() {} public Node(int _val) { val = _val; } public Node(int _val,Node _left,Node _right) { val = _val; left = _left; right = _right; } }; */ class Solution { Node pre, head; public Node treeToDoublyList(Node root) { if(root==null)return null; dfs(root); head.left = pre; pre.right = head; return head; } public void dfs(Node cur){ if(cur == null) return; dfs(cur.left); if(pre!=null){ pre.right = cur; }else{ head = cur; } cur.left = pre; pre = cur; dfs(cur.right); } }