1. 程式人生 > >二叉搜尋樹與雙向連結串列(沒有優化的時間效率比較低)

二叉搜尋樹與雙向連結串列(沒有優化的時間效率比較低)

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;          //當左子樹為空時,則返回根節點,不然返回左子樹
         
     }
}