一,問題描述
給定一棵二叉搜尋樹,在二叉搜尋樹的基礎上,將之轉換成有序的雙向鍊錶。即,不需要額外的輔助空間。
二,問題分析
對於二叉搜尋樹而言,它的結點有左孩子和右孩子指標。這類似於雙向鍊錶中的 前向指標(指向前驅結點) 和 後向指標(指向下乙個結點)。另外,二叉搜尋樹中序遍歷是有序的。在中序遍歷二叉搜尋樹時,將原來指向左子結點的指標調整為鍊錶中的指向前乙個結點的指標;將原來指向右子結點的指標調整為鍊錶中的指向下乙個結點的指標。
當遍歷到根結點時,可以將樹視為三個部分:根結點、根結點的左子樹、根的右子樹。找出根結點的左子樹中的最大值,將根的左孩子指向它;找出根結點的右子樹中的最小值,將根的右孩子指向它。而這個過程,其實就是二叉搜尋樹的中序遞迴遍歷隱含的過程。
根據中序遞迴,當遍歷轉換到根結點時,根的左子樹已經轉換成乙個有序的雙向鍊錶了,此時:雙向鍊錶的最後乙個結點就是根的左子樹中最大的結點。下乙個待轉換的結點就是根。當根轉換完成後,就遍歷根的右子樹進行轉換。
轉換後:
三,**實現
①首先需要構造一棵二叉排序樹,由buildtree方法實現,可參考:二叉樹的構造
②對結點進行轉換,主要由convertnode(binarynode, binarynode)方法實現
11)在轉換的過程中,鍊錶長度是不斷增加的。第7行方法裡面的第二個引數lastnode,用來記錄:當前鍊錶中的最後乙個結點。/**2
* 採用中序遍歷思想將二叉搜尋樹的結點轉化為雙向鍊錶的結點3*
@param
root 從二叉搜尋樹的根開始轉換4*
@param
lastnode 當前鍊錶的最後乙個結點5*
@return
鍊錶的最後乙個結點6*/
7private binarynode convertnode(binarynode root, binarynode lastnode)
2)第11行的currentnode就是 當前正在轉換的結點。第12、13行表示,轉換currentnode的左子樹。當currentnode的左子樹轉換完成之後,程式執行到第15行,將currentnode的左孩子賦值給當前鍊錶中的最後乙個結點。
3)第17行 有個if判斷,主要是:對於雙向鍊錶中的第乙個結點而言(即:二叉搜尋樹中的最左下結點(值最小的結點),比如那個權值為4的結點),它是左孩子是null的。因為它是值最小的結點啊。如果lastnode不為null,表明:至少已經將二叉搜尋樹中的部分結點轉化成了雙向鍊錶中的結點了。因此,需要將雙向鍊錶中的最後乙個結點的右孩子指標指向當前正在轉換的結點。
4)第19行,表示當前正在轉換的結點已經轉換完成了,故它變成了雙向鍊錶中的最後乙個結點。
5)第21行,繼續遞迴轉換當前結點的右子樹。
6)第24行,返回整棵二叉搜尋樹轉換完成之後的 得到的 雙向鍊錶的尾結點。
7)由於每個結點只會遍歷一次,故演算法的時間複雜度為o(n);由於直接在是原來的二叉搜尋樹中進行鍊錶結點的轉換,故空間複雜度為o(1)
四,完整**
//將二叉搜尋樹轉化為有序的雙向鍊錶
public
class bst2list
@override
public
int compareto(binarynode node)
@override
public string tostring()
}private binarynode root;
public
void buildtree(int ele)
}private
void insert(int ele)
private binarynode insert(binarynode root, int ele)
//將二叉搜尋樹轉化成雙向鍊錶,返回鍊錶的頭結點
public binarynode bstconvert2list(binarynode root)
return head;
}/**
* 採用中序遍歷思想將二叉搜尋樹的結點轉化為雙向鍊錶的結點
* @param
root 從二叉搜尋樹的根開始轉換
* @param
lastnode 當前鍊錶的最後乙個結點
* @return
鍊錶的最後乙個結點
*/private binarynode convertnode(binarynode root, binarynode lastnode)
public
void printlist(binarynode head)}//
hapjin test
public
static
void main(string args) ;
bst2list obj = new bst2list();
obj.buildtree(eles);
binarynode head = obj.bstconvert2list(obj.root);
obj.printlist(head);}}
二叉搜尋樹轉換成雙向鍊錶
問 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。要求不能建立任何新的結點,只能調整樹中結點指標的指向。public class treenode public class solution 如果已經遍歷到葉子節點,則將最後的節點轉變成葉子節點 if prootoftree.left ...
二叉搜尋樹轉換成排序雙向鍊錶
因為二叉樹中,每個結點都有兩個指向子節點的指標。在雙向鍊錶中也有兩個指標,它們分別指向前乙個和後乙個結點。由於這兩種結點的結構相似,同時二叉搜尋樹也是一種排序的資料結構,因此在理論上可能實現二叉搜尋樹和排序鍊錶的雙向鍊錶的轉換。在搜尋二叉樹中,左子節點的值總小於父節點的值,右子節點的值總是大於父節點...
將二叉查詢樹轉換成有序雙向鍊錶
一 問題描述 輸入一棵二叉搜尋樹,現在要將該二叉搜尋樹轉換成乙個排序的雙向鍊錶。而且在轉換的過程中,不能建立任何新的結點,只能調整樹中的結點指標的指向來實現。二 實現思路 在二叉搜尋樹中,每個結點都有兩個分別指向其左 右子樹的指標,左子樹結點的值總是小於父結點的值,右子樹結點的值總是大於父結點的值。...