比如輸入圖4.12 中左邊的二叉搜尋樹,則輸出轉換之後的排序現向鍊錶。
在二叉樹中,每個結點都有兩個指向子結點的指標。在雙向鍊錶中,每個結點也有兩個指標,它們分別指向前乙個結點和後乙個結點。由於這兩種結點的結構相似,同時二叉搜尋樹也是一種排序的資料結構,因此在理論上有可能實現二叉搜尋樹和排序的雙向鍊錶的轉換。在搜尋二叉樹中,左子結點的值總是小於父結點的值,右子結點的值總是大於父結點的值。因此我們在轉換成排序雙向鍊錶時,原先指向左子結點的指標調整為鍊錶中指向前乙個結點的指標,原先指向右子結點的指標調整為鍊錶中指向後乙個結點指標。接下來我們考慮該如何轉換。
由於要求轉換之後的鍊錶是排好序的,我們可以中序遍歷樹中的每乙個結點, 這是因為中序遍歷演算法的特點是按照從小到大的順序遍歷二叉樹的每乙個結點。當遍歷到根結點的時候,我們把樹看成三部分:值為10 的結點、根結點值為6 的左子樹、根結點值為1 4 的右子樹。根據排序鍊錶的定義,值為10 的結點將和它的左子樹的最大乙個結點(即值為8 的結點)鏈結起來,同時它還將和右子樹最小的結點(即值為12 的結點)鏈結起來,如圖4.13 所示。
按照中序遍歷的順序, 當我們遍歷轉換到根結點(值為10 的結點)時,它的左子樹已經轉換成乙個排序的鍊錶了, 並且處在鍊錶中的最後乙個結點是當前值最大的結點。我們把值為8 的結點和根結點鏈結起來,此時鍊錶中的最後乙個結點就是10 了。接著我們去地歷轉換右子樹, 並把根結點和右子樹中最小的結點鏈結起來。至於怎麼去轉換它的左子樹和右子樹,由於遍歷和轉換過程是一樣的,我們很自然地想到可以用遞迴。
#include#includeusing namespace std;
struct binarytreenode
;binarytreenode* createbinarytreenode(int val)
void connecttreenodes(binarytreenode* parent,binarytreenode* left,binarytreenode* right)
}void in(binarytreenode* root)
void convertnode(binarytreenode* node,binarytreenode** lastlist)
binarytreenode* convert(binarytreenode* root)
void printlist(binarytreenode* root)
cout<
面試題27 二叉搜尋樹與雙向鍊錶
題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。解 見 注釋 struct treenode class solution void convert treenode proot,treenode plastnodeinli...
面試題27 二叉搜尋樹與雙向鍊錶
題目 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。比如輸入下圖中左邊兒茶搜尋樹,則輸出轉換後的排序雙向鍊錶。10 614 4 812164 6 8 10 12 14 16 將二叉搜尋樹轉化為有序雙向鍊錶,類似於中序遍歷,中序遍歷的...
面試題27 二叉搜尋樹與雙向鍊錶
題目 輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換為乙個排序的雙向鍊錶。要求不能建立 任何新的結點,只能調整樹種結點指標的指向。比如輸入下圖的二叉搜尋樹,則輸出轉換 後的雙向排序鍊錶。1 102 36 144 54 81216 轉換後的雙向排序鍊錶為 1468 1012 1416 首先 要明白二叉搜尋樹是...