劍指Offer27 二叉樹轉雙向鍊錶問題

2021-09-26 22:04:55 字數 1774 閱讀 7562

* 問題描述

* 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。「要求不能建立任何新的結點」,只能調整樹中結點指標的指向。例如輸入前序遍歷為

* 10、6、4、8、14、12、16的二叉搜尋樹,其輸出的轉換後排序雙向鍊錶為:4、6、8、10、12、14、16

* 問題分析:

* 在二叉樹中,每個結點都有兩個指向子結點的指標。在雙向鍊錶中,每個結點也有兩個指標,它們分別是指向前乙個結點和後乙個結點。由於這兩個結點的

* 結構相似,同時二叉搜尋樹也是一種排序的資料結構,因此在理論上有可能實現二叉搜尋樹和排序的雙向鍊錶的轉換。在二叉搜尋樹中,左子結點的值總是小於父結點

* 的值,有子結點的值總是大於父結點的值。因此在轉換成排序的雙向鍊錶時,原先指向左子結點的指標調整為鍊錶中指向前乙個結點的指標,原先指向右子結點

* 的指標調整為鍊錶中指向後乙個結點指標。

* 由於要求轉換後的鍊錶是排序好的,因此可以用中序遍歷來操作,對於二叉查詢樹而言,其中序遍歷序列就是從小到大排序的。當遍歷到根結點的時候,我們把

* 樹看成三個部分:值為10的根結點,根結點值為6的左子樹,根結點值為14的右子樹。根據排序鍊錶的定義,值為10的結點將和它的左子樹的最大乙個結點(值為8的結點)

* 鏈結起來,同時它將和右子樹最小的結點(即值為12的結點)鏈結起來。

public class code027 

}//定義雙向鍊錶的左邊頭結點和右邊頭結點,初始化為null

static binarytreenode lefthead=null;

static binarytreenode righthead=null;

private static binarytreenode convert(binarytreenode prootoftree)

//第一次執行時,它會使最左邊的葉子結點為鍊錶的第乙個節點

convert(prootoftree.pleft);

if(righthead==null)else

//把右葉子結點也插入到雙向鍊錶(righthead已確定,直接插入)

convert(prootoftree.pright);

//返回左邊頭結點,也可以返回右邊頭結點

return lefthead;

}//非遞迴法:借助棧來儲存中序遍歷的結果順序

private static binarytreenode convertbsttobilist(binarytreenode proot)

//定義棧用於儲存中序遍歷的結點順序

stackstack=new stack<>();

binarytreenode p=proot;

binarytreenode pre=null;//用於儲存中序遍歷的上乙個結點

boolean isfirst=true;

while (p!=null|| !stack.isempty())

//找到左子樹的最左葉子結點,即為中序遍歷的第乙個結點

p=stack.pop();

if(isfirst)else

p=p.pright;

}return proot;

}//定義二叉樹的結點類

private static class binarytreenode

public binarytreenode(int value)

}}

劍指offer 27 二叉樹的映象

宣告 本系列部落格是對何海濤 劍指offer 的關鍵點總結。1.樹的映象 定義 樹的根結點相同,但是左右兩個子節點交換了位置 2.解題思路 1 前序遍歷樹的每乙個結點 2 如果遍歷到的節點有子節點,則交換其左右兩個子節點 3 分別以左子節點和右子節點作為新的根結點,遞迴呼叫該函式 4 當遍歷到的結點...

劍指Offer 27 二叉樹的映象

請完成乙個函式,輸入一棵二叉樹,該函式輸出它的映象。例 8 8 6 10 10 6 5 7 9 11 11 9 7 5交換左右子樹,遍歷至葉節點終止即可。時間複雜度 o n 空間複雜度 o 1 def mirror of binary tree root param root root return...

劍指offer 27 二叉樹的映象

思路 先前序遍歷這顆樹的每個節點,如果遍歷到的節點有子節點,就交換它的兩個子節點。當交換完所有非葉節點的左右節點之後就得到了樹的映象。class treenode def init self,x self.val x self.left none self.right none class solu...