Q27 二叉搜尋樹與雙向鍊錶

2021-06-21 09:51:31 字數 1117 閱讀 3407

q:輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換為乙個排序的雙向鍊錶。要求不能建立任何新的結點。

分析:二叉搜尋樹的中序遍歷就是乙個有序的序列,而樹的左孩子指標和有孩子指標當然就充當了前驅和後繼指標,所以這種轉換是自然的。

我們定義結構體如下:

struct treenode

};

回想中序遍歷的模板:

void inordervisit(treenode *root)

該題目中,visit函式顯然不是僅僅列印出這個值這麼簡單,但其實質還是一樣的,既然中序訪問各個節點的順序是有序的,那麼我們只需要將訪問到的結點掛在到乙個雙向鍊錶上就可以,想想我們建立乙個雙向鍊錶的過程,在鍊錶的表尾,建立新的結點,將其與表尾的結點連線,由於不允許我們使用額外的結點,所以這裡就要求我們判斷煉表頭結點是否為空的情況。若沒有這個限制,像我們在進行鍊錶的操作的時候,為了統一操作,我們總是會建立乙個只起到統一操作的表頭節點,其中不包含任何有用資訊。

那麼現在我們設計下我們程式的大體流程,以及需要哪些引數。

首先,我們要不停的修改雙向鍊錶,所以要有乙個二級指標,或者是一級指標的引用,這裡我們選擇使用引用&。

接下來,在visit功能塊裡,我們把訪問的結點掛到鍊錶的表尾。

因為是雙向的,所以即使我們只記錄鍊錶尾結點,通過迴圈向前尋找,我們是可以得到鍊錶的表頭的。

void treetolink(treenode *root,treenode *&linktail)

//handle its right_sub_tree

treetolink(root->right,linktail);

}

最終,我們得到的linktail是乙個尾結點,我們可以通過left指標域向前遍歷,得到頭,至此,問題就解決了。

總結:

這類的問題很多,但都有乙個共性,就是他們都是三種遞迴遍歷的變種,不同的是visit的處理,但都可以套用模板。

參考書裡給出的解法也不錯,但個人覺得有點麻煩,既然有模板,我們還是推薦套用模板,就像我們高考時的作文,自己熟練掌握幾套模板總是很受用的,所謂萬變不離其蹤。

劍指27 二叉搜尋樹與雙向鍊錶

輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。解題思路 1 用遞迴,節點的左鍊錶相鄰節點為該節點的左子樹最右節點,節點的右鍊錶的相鄰節點為該節點的右子樹的最左節點 2 用非遞迴,中序遍歷 記錄節點的前乙個節點 方法一 遞迴,先判斷左...

27 二叉搜尋樹轉換為雙向鍊錶

題目描述 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。思路 首先需要明白二叉搜尋樹也是一種排序的資料結構,它的中序遍歷就是乙個不遞減的順序排列 所以如果要轉換成乙個排序好的雙向鍊錶,那麼僅需要改變原來指向左子節點和右子節點的指標,...

二叉搜尋樹與雙向鍊錶

1.問題描述 輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。來自 劍指offer 2.分析 對於二叉搜尋樹我們知道,樹的左孩子都比根節點要下,樹的右孩子都比根結點要大,根據這個特點,我們進行中序遍歷得到的序列就會滿足題目的要求,我們...