題目描述:有乙個搜尋二叉樹,對於樹中的任意乙個節點,其左子樹的所有值小於該節點的值,而其右子樹的所有值大於該節點的值。要求:在不定義任何新的節點情況下,將該二叉樹轉換成為乙個排序雙向鍊錶。
假設有上面的二叉樹,那麼其轉換為雙向鍊錶後的順序應該為:2 3 4 5 6 7 8
對於煉表頭節點:其直接前驅為空指標,直接後繼為其父節點;
對於鍊錶尾節點:其直接前驅為其父節點,直接後繼為空;
對於左子樹的根節點:其直接前驅為其左子樹中的最大值;其直接後繼為其右子樹中的最小值或者父節點的值;
對於右子樹的根節點:其直接前驅為其左子樹中的最大值或者父節點的值;其直接後繼為右子樹中的最大值;
因此,我們可以將二叉樹看作三個部分:根節點、左子樹、右子樹。
如果我們可以遞迴地將左子樹和右子樹轉換成為排序的雙向鍊錶,那麼整個二叉樹也就被轉換成了排序的雙向鍊錶。
示例**如下:
#includeusing將上述**對上面圖示的二叉樹進行轉換,其轉換過程中的變數變化如下,這能幫助我們理解整個轉換的過程:namespace
std;
struct
bintreenode
;void convertnode(bintreenode *pnode, bintreenode **plastnodeinlist);
bintreenode *convert(bintreenode *prootnode)
//返回鍊錶的頭節點
return
pheadoflist;
}void convertnode(bintreenode *pnode, bintreenode **plastnodeinlist)
bintreenode *pcurrentnode =pnode;
//如果存在左子樹,那麼遞迴地修改左子樹節點指向
if (pcurrentnode->leftnode != nullptr)
//將當前節點的左子節點指向鍊錶尾部元素(因為鍊錶尾部元素更小)
pcurrentnode->leftnode = *plastnodeinlist;
//將鍊錶尾部元素的右子節點指向當前節點,與上一步操作類似;
if (*plastnodeinlist != nullptr)
//更新鍊錶尾部元素
*plastnodeinlist =pcurrentnode;
//遞迴的修改右子樹的節點指向
if (pcurrentnode->rightnode !=nullptr)
}int
main()
{}
在convert函式中呼叫convertnode()函式結束以後,用來儲存鍊錶尾部元素的變數值為二叉樹的根節點的值,即:10。
因此,為了正確地返回鍊錶頭部元素,需要將該指標向左移到煉表頭地位置,最終將這個指標返回。
將二叉搜尋樹轉換為雙向鍊錶
題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。好悲傷,面試微軟的時候被遇到這個題,知道大體思路,但是最終 沒寫好,由此可見平常學東西不紮實。總是淺嘗輒止。思路 使用中序遍歷,儲存已經建好的雙向鍊錶的最後乙個節點。那麼處理當...
將二叉搜尋樹轉換為雙向鍊錶
二叉搜尋樹的定義 若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值 它的左 右子樹也分別為二叉排序樹。題目描述 輸入一棵二叉搜尋樹,將其轉換為排序的雙向鍊錶,要求是不能建立任何新的節點,只能調整樹中節點指標的指向。public...
將二叉樹轉換為排序雙向鍊錶
對二叉樹進行中序遍歷,得到乙個排序的序列,然後調整樹節點的指標即可得到 版本1 非遞迴 treenode convert treenode prootoftree p stacktree.top stacktree.pop if flag else p p right return root 版本2...