【劍指offer】二叉搜尋樹與雙向連結串列
阿新 • • 發佈:2019-01-07
二叉搜尋樹與雙向連結串列
題目描述
輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。
解題思路
- 非遞迴版
- 核心是中序遍歷的非遞迴演算法。
- 修改當前遍歷節點與前一遍歷節點的指標指向
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
import java.util.Stack;
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null)
return null;
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode p = pRootOfTree;
TreeNode pre = null;// 用於儲存中序遍歷序列的上一節點
boolean isFirst = true;
while(p!=null||!stack.isEmpty()){
while(p!=null){
stack.push(p);
p = p.left;
}
p = stack.pop();
if(isFirst){
pRootOfTree = p;// 將中序遍歷序列中的第一個節點記為root
pre = pRootOfTree;
isFirst = false;
}else{
pre.right = p;
p.left = pre;
pre = p;
}
p = p.right;
}
return pRootOfTree;
}
}
- 遞迴版
- 將左子樹構造成雙鏈表,並返回連結串列頭節點。
- 定位至左子樹雙鏈表最後一個節點。
- 如果左子樹連結串列不為空的話,將當前root追加到左子樹連結串列。
- 將右子樹構造成雙鏈表,並返回連結串列頭節點。
- 如果右子樹連結串列不為空的話,將該連結串列追加到root節點之後。
- 根據左子樹連結串列是否為空確定返回的節點。
/**
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree==null)
return null;
if(pRootOfTree.left==null&&pRootOfTree.right==null)
return pRootOfTree;
// 1.將左子樹構造成雙鏈表,並返回連結串列頭節點
TreeNode left = Convert(pRootOfTree.left);
TreeNode p = left;
// 2.定位至左子樹雙鏈表最後一個節點
while(p!=null&&p.right!=null){
p = p.right;
}
// 3.如果左子樹連結串列不為空的話,將當前root追加到左子樹連結串列
if(left!=null){
p.right = pRootOfTree;
pRootOfTree.left = p;
}
// 4.將右子樹構造成雙鏈表,並返回連結串列頭節點
TreeNode right = Convert(pRootOfTree.right);
// 5.如果右子樹連結串列不為空的話,將該連結串列追加到root節點之後
if(right!=null){
right.left = pRootOfTree;
pRootOfTree.right = right;
}
return left!=null?left:pRootOfTree;
}
}