將二叉查詢樹轉換成有序雙向鍊錶

2022-08-15 18:12:11 字數 1366 閱讀 1329

一、問題描述

輸入一棵二叉搜尋樹,現在要將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。而且在轉換的過程中,不能建立任何新的結點,只能調整樹中的結點指標的指向來實現。

二、實現思路

在二叉搜尋樹中,每個結點都有兩個分別指向其左、右子樹的指標,左子樹結點的值總是小於父結點的值,右子樹結點的值總是大於父結點的值。而在雙向鍊錶中,每個結點也有兩個指標,它們分別指向前乙個結點和後乙個結點。所以這兩種資料結構的結點是一致,二叉搜尋樹之所以為二叉搜尋樹,雙向鍊錶之所以為雙向鍊錶,只是因為兩個指標的指向不同而已,通過改變其指標的指向來實現是完全可能的。

例如如下的二叉搜尋樹,

若採用中序遍歷,其遍歷順序為1-2-3-4-5-6-7,通過適當的指標變換操作,可變成的雙向有序鍊錶如下:

從上圖,我們可以看出,為了減少指標的變換次數,並讓操作更加簡單,在轉換成排序雙向鍊錶時,原先指向左子結點的指標調整為鍊錶中指向前乙個結點的指標,原先指向右子結點的指標調整為鍊錶中指向下乙個結點的指標。例如對於上面的值為2的指點,調整後,它的前乙個結點為1,後乙個結點為3,而結點2的左子結點本來就為1,右子結點本來就為3.

對於樹的操作,通常是在遍歷樹的各個結點的過程中,通過對結點實施某些操作來完成的,這個演算法也不例外。由於要求轉換後的雙向鍊錶也是有序的,而我們從上面也可以看到,當我們以中序遍歷二叉搜尋樹時,其遍歷的結點就是有序的,所以在這裡我位採用的遍歷順序應該是中序。

那麼我們應該如何調整指標,讓二叉搜尋樹變成乙個雙向有序鍊錶呢?當遍歷到根結點時,我們可以把樹看成三個部分:根結點,根的左子樹和根的右子樹。如上圖的二叉排序樹,就分成了根結點4、以結點2為根的左子對和以結點6為根的右子樹。從變換的鍊錶中我們可以看到,應當把結點4的left指標指向結點3,把結點3的right指標指向結點4,而由於我們採用的是中序遍歷,所以當我們遍歷到結點4時,結點4的左子樹已經轉化為乙個有序的雙向鍊錶,而結點3是這個已經轉化的雙向鍊錶的尾結點,所以我們應該用乙個變數last_node來儲存最後乙個結點的指標,以便在與根結點連續時使用。然後把這個變數last_node的值更新為指向根結點4。對於結點4的右子樹,採取相似的操作。至於具體的實現,我們只需要對所有的子樹遞迴地執行上述操作即可。其操作過程如下:

1

struct

binarytreenode

2; 78

/*9遞迴遍歷中的轉換過程

10引數:處理當前結點,當前鍊錶的最後乙個結點(初始值為空)

11*/

12void convertnode(binarytreenode* pnode, binarytreenode**plastnodeinlist)

13

3031 binarytreenode* convert(binarytreenode*prootintree)

32

二叉搜尋樹轉換成有序的雙向鍊錶

一,問題描述 給定一棵二叉搜尋樹,在二叉搜尋樹的基礎上,將之轉換成有序的雙向鍊錶。即,不需要額外的輔助空間。二,問題分析 對於二叉搜尋樹而言,它的結點有左孩子和右孩子指標。這類似於雙向鍊錶中的 前向指標 指向前驅結點 和 後向指標 指向下乙個結點 另外,二叉搜尋樹中序遍歷是有序的。在中序遍歷二叉搜尋...

將二叉樹轉換成雙向鍊錶

思路 採用中序遍歷的方法,visit函式須要完畢的功能為 1 當前節點的左子節點指向上一次訪問的節點 2 將上一次訪問節點的右子節點指向當前節點 3 最後更新上一次訪問節點為當前節點。在第二步時須要推斷上一次訪問節點是不是為null,假設是,則第二步改為鍊錶的頭結點指向當前節點。程式例如以下 str...

鍊錶 將二叉搜尋樹轉換成雙向鍊錶

一 使用佇列 t o n s o n 按照二叉樹中序遍歷的順序,將每個節點放在佇列中 從佇列中依次彈出節點,並按照彈出的順序依次連線節點 public static node convert node root node head q.poll node pre head node cur null...