題目:輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶,要求不能建立任何新的結點,只能調整樹中結點指標的指向。
只能修改節點中的指標,那麼簡單一點的情形,應該就是將二叉樹節點中的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...