劍指offer_26:二叉搜尋樹和雙向連結串列
阿新 • • 發佈:2021-01-21
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的迴圈雙向連結串列。要求不能建立任何新的節點,只能調整樹中節點指標的指向。
為了讓您更好地理解問題,以下面的二叉搜尋樹為例:
我們希望將這個二叉搜尋樹轉化為雙向迴圈連結串列。連結串列中的每個節點都有一個前驅和後繼指標。對於雙向迴圈連結串列,第一個節點的前驅是最後一個節點,最後一個節點的後繼是第一個節點。
下圖展示了上面的二叉搜尋樹轉化成的連結串列。“head” 表示指向連結串列中有最小元素的節點。
特別地,我們希望可以就地完成轉換操作。當轉化完成以後,樹中節點的左指標需要指向前驅,樹中節點的右指標需要指向後繼。還需要返回連結串列中的第一個節點的指標。
1、迭代
/* // 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 { public Node treeToDoublyList(Node root) { if(root==null) return null; Stack<Node> stack=new Stack<>(); Node cur=root,pre=null,head=null; while(!stack.isEmpty()||cur!=null){ while(cur!=null){ stack.push(cur); cur=cur.left; } cur=stack.pop(); if(pre==null){ head=cur; }else{ //處理節點關係 pre.right=cur; cur.left=pre; } //轉移指標 pre=cur; cur=cur.right;//看看右子節點是否為空 } //處理首尾指標 pre.right=head; head.left=pre; return head; } }
2、遞迴
/* // 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 node){ if(node==null){ return; } dfs(node.left);//左子節點 if(pre==null){ head=node; }else{ pre.right=node; node.left=pre; } pre=node; dfs(node.right);//右子節點 } }