二叉搜尋樹與雙向連結串列(沒有優化的時間效率比較低)
package niuke;
public class SearchTreenode1 {
public static void main(String[] args) {
}
public TreeNode Convert(TreeNode pRootOfTree) {
/* 輸入一棵二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立任何新的結點,只能調整樹中結點指標的指向。*/
/*對於第16行程式碼到第30行程式碼,當使用遞迴就把已經遞迴的結果當做一個雙向連結串列來看了,就用以實現的最理想的狀態來對待,。
* 對於第12行程式碼到第16行程式碼則就是遞迴到最後一步的時候應該想到的情況
* 整體的思想就是如果是單純的只有3個節點的樹的話,左邊要的是一個點,但是必須呼叫遞迴的結果還是那一個點,是怎麼做的。但是如果把左節點想成一個樹,結果應該的返回的是什麼結果,如果把右節點想成一個樹,應該返回的是什麼結果
* 然後建立連線,這是又要想這時返回給上一級遞迴的是什麼,如果已經完成的這棵樹是左子樹應該返回什麼,是右子樹應該返回什麼*/
//中序遍歷的遞迴演算法,本人認為遞迴演算法寫的時候,首先想到如果這是最後一個節點最後一個樹,最簡單的情況,這時候要怎麼寫,還要想到,如果返回的是一個大樹,要怎麼寫
if(pRootOfTree == null) //如果是空節點則返回空節點
return null;
if(pRootOfTree.left == null && pRootOfTree.right == null) { //如果左端是葉子節點,也是遞迴到最後的情況,也是要想到的最簡單的情況
return pRootOfTree;
}
TreeNode left = Convert(pRootOfTree.left); //如果左端是個樹,好了那就直接推給遞迴去做,這時候必須要保證遞迴左樹返回的是,左樹的最後節點
TreeNode p = left;
while( p != null && p.right != null) { //則就承接了上2行程式碼,這你想到返回的p是不斷遞迴之後的結構,已經構成了雙向連結串列所以一直取右節點找到右節點
p = p.right;
}
if(left != null) {
p.right = pRootOfTree; //這就是建立連線,把根節點與左子樹建立聯絡
}
TreeNode right = Convert(pRootOfTree.right); //然後呼叫遞迴把右子樹進行遞迴返回其頭結點
if(right != null) {
right.left = pRootOfTree; //把根節點與右子樹建立聯絡
pRootOfTree.right = pRootOfTree;
}
return left!=null?left:pRootOfTree; //當左子樹為空時,則返回根節點,不然返回左子樹
}
}