劍指Offer 面試題27 二叉搜尋樹與雙向鍊錶

2022-08-12 02:57:11 字數 1429 閱讀 1854

題目:輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶,要求不能建立任何新的結點,只能調整樹中結點指標的指向。

只能修改節點中的指標,那麼簡單一點的情形,應該就是將二叉樹節點中的lchild指標當做轉化後雙向鍊錶中的prev指標,rchild指標當做next指標。

思路類似於嚴蔚敏《資料結構》中的線索二叉樹,但是略不同的地方是,對於乙個有左子樹的節點來說,他的左孩子指標要指向左子樹中最大的節點,而不是原本的左孩子。舉個典型的例子,根節點應當指向左子樹的右孩子的右孩子的右孩子(只要存在右孩子,就一直繼續下去)。同理,對於乙個有右子樹的節點來說,原本的右孩子指標應當指向右子樹中最小的節點,而不是原本的右孩子。

通過getleftmax來得到左子樹中的最大節點,通過getrightmin來得到右子樹中的最小節點,然後把這兩個節點和根節點正確的連線即可。每次連線要操作4個指標,分別是把左側最大的rchild指向根節點,根節點的lchild指向左側最大,右側最小的lchild指向根節點,根節點rchild指向右側最小。當然這是在這個根節點的左右子樹都存在的情況下的討論。

我的**用c/c++實現。

以下是資料結構定義的**:

#include #include using namespace std;

#define null 0

typedef struct treenodetreenode;

以下是轉換演算法的**:

treenode* getleftmax(treenode* const);

treenode* getrightmin(treenode* const);

treenode* linknode(treenode* const proot)

if (proot->rchild)

return proot;

}treenode* getleftmax(treenode* const proot)

treenode* getrightmin(treenode* const proot)

treenode* getheadnodeofdulinklist(treenode* const proot)

return phead;

}

以下是測試用的**,你也可以自己做一些改動:

static void buildtree(treenode* &proot)

static void deletetree(treenode* proot)

static void deletedulinklist(treenode* phead)

free(phead); }}

static void printdulinklist(treenode* const phead)while(ptemp); }}

int main()

只是跟書上給的不太一樣。

劍指offer 面試題27 二叉搜尋樹與雙向鍊錶

題目 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶,要求不能建立任何新節點,只能調整樹中結點指標的指向。最後輸出排序後雙向鍊錶。基本思想 二叉樹中每個節點都有兩個指向子節點的指標。在雙向鍊錶中,每個節點也有兩個指標,分別指向前乙個節點和後乙個節點。二叉搜尋樹中,左子節點的值總是小於父節...

劍指Offer 面試題27 二叉搜尋樹與雙向鍊錶

題面 劍指offer p151 牛客網 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。如 如果不考慮箭頭,可以看到4 6 8 10 12 14 16是樹的中序遍歷 因此可以借用中序遍歷的方法進行修改 struct treenode ...

劍指offer面試題27 二叉搜尋樹與雙向鍊錶

題目 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。思路 二叉搜尋樹左小右大,中序遍歷。當前結點左結點連線左子樹最大值,左子樹最大值右結點連線當前節點,以當前結點為最大值,以右子樹和最大值遞迴。include using names...