首先須要明白二叉搜索樹也是一種排序的數據結構,它的中序遍歷就是一個不遞減的順序排列數據結構
因此若是要轉換成一個排序好的雙向鏈表,那麼僅須要改變原來指向左子節點和右子節點的指針,讓他們分別指向前節點和後節點便可,如圖所示spa
調整指針指針
原先指向左子節點的指針調整爲鏈表中指向前一個節點的指針排序
原先指向右子節點的指針調整爲鏈表中指向後一個節點的指針遞歸
如何調整it
考慮根節點和左右子樹的根本狀況,由於若是用遞歸,這種根本狀況考慮就能夠去將一樣的方法用到左右子樹上ast
對於這種基本狀況,能夠分紅三個部分來看,根節點10,左子樹,右子樹,須要作的就是將10與左子樹中的最大值連起來,而後把10與右子樹中的最小值連起來class
如今有個問題就是咱們並不知道左子樹中的最大值和右子樹中的最小值,若是咱們知道就行了。可是想到遞歸,遞歸到左子樹中,若是左子樹已轉換爲雙向鏈表,那麼雙向鏈表的最後一個節點就是咱們想要的,而右子樹中的第一個節點也是咱們想要的搜索
轉換代碼遍歷
public static BinaryTreeNode baseconvert(BinaryTreeNode root, BinaryTreeNode lastNode) {
if (root == null)
return lastNode;
BinaryTreeNode current = root;
if (current.leftNode != null)
lastNode=baseconvert(current.leftNode, lastNode);
current.leftNode = lastNode;
if (lastNode != null)
lastNode.rightNode = current;
lastNode = current;
if (current.rightNode != null)
lastNode=baseconvert(current.rightNode, lastNode);
return lastNode;
}
至於爲何須要一個lastNode,
上面的代碼中有兩個參數,一個是根節點,一個是已經轉換好的鏈表的最後一個節點,由於二叉搜索樹中序遍歷的特性,當遍歷到根節點的時候,左子樹已經排好序了,因此會有一個左子樹已經轉換好的鏈表,而這個鏈表的最後一個節點便是咱們須要和根節點左連的節點
至於爲何須要一個lastNode,假設當前節點的左子樹都排好序,那麼如今lastNode應該是左子樹的最大節點(也就是左子樹的右兒子的右兒子的右兒子直到沒有右兒子的那個節點。)若是不保存lastNode找到當前節點的左子樹的最大節點是不容易的。
另外須要說明的是lastNode指向的是已經排好序的雙向鏈表的尾節點(這個尾節點的pre已經指向完畢了,右節點還沒處理好。)
最開始的時候lastNode爲null
current爲當前子樹的根節點
若是左子樹存在,那麼轉換左子樹,遞歸下去,遞歸返回以後,說明找到了鏈表的第一個節點,也就是4那個節點,將4的前面節點置爲null,此時current爲4那個節點,這個時候因爲6的4這個左子樹已遍歷完了,因此須要往上層返回,返回以前須要將current賦值給lastNode,說明4這個左子樹的最後一個節點就是4
因爲往上返回了一層,此時的current已是6了,將6的左節點賦值爲以前返回的4,判斷以前返回的lastNode是否爲null,不爲空說明須要把根節點和lastNode連起來,其實lastNode爲null的狀況就只有第一個節點會出現,其餘的時候都不會出現。如今已排好序的包括6的左子樹以及6自己了,因此此時的lastNode爲6
6和4的雙向鏈接就完成了,因爲6的右子樹存在,又會遞歸到右邊子樹去,因爲8不存在左右子樹,遞歸下去一層以後current就是8這個節點,但它的左孩子爲空,因此不會左邊遞歸下去,將8的左鏈接與以前的lastNode鏈接起來,創建雙向鏈接的一條鏈接,而後因爲lastNode不爲空,因此又把lastNode的右鏈接與8鏈接起來,至此雙向鏈接創建,此時lastNode爲8
因此468都已排好序,此時lastNode爲8,返回到上一層,也就是根節點10了,在這一層current爲10,將current的左鏈接與lastNode鏈接起來,若是lastNode存在,將lastNode的右鏈接與10鏈接一塊兒,以此創建雙向鏈接。至此就將根節點和左子樹都鏈接起來了,而後就是去轉換右子樹,如今的lastNode爲10,current爲14,14有左孩子,因此須要遞歸到下一層,下一層的current爲12,12沒有左孩子,因此不用在坐遞歸,因此12是12這棵子樹轉換成雙向鏈表的最左邊的節點,將lastNode與12鏈接,也就是10與12鏈接,此時的lastNode就變成了12,再將12的右子樹遞歸,因爲沒有右子樹,因此直接返回到上一層,上一層的current是14,14與已排好序的lastNode鏈接,也就是12與14鏈接,而後lastNode變爲14,遞歸到14的右子樹,也就current變爲16,16再遞歸左子樹,無左子樹,將16與14鏈接,此時的lastNode變爲16,遞歸右子樹,無右子樹,因此整個遞歸工做完成