1. 程式人生 > >劍指offer:二叉搜尋樹與雙向連結串列(java)

劍指offer:二叉搜尋樹與雙向連結串列(java)

題目:輸入一顆二叉搜尋樹,將該二叉搜尋樹轉換成一個排序的雙向連結串列。要求不能建立新的結點,只能調整樹中結點指標的指向。

比如如下圖中的二叉搜尋樹,則輸出轉換之後的排序雙向連結串列為:

    由於要求轉換之後的連結串列是排好序的,我們可以中序遍歷樹的每一個結點,這是因為中序遍歷演算法的特點是按照從小到大的順序遍歷二叉樹的每一個結點。當遍歷到根結點的時候,我們把樹看成三部分:值為10的結點、根結點為6的左子樹、根結點為14的右子樹。根據排序連結串列的定義,值為10的結點將和它左子樹最大一個結點連結起來,同時它還將和右子樹的最小的結點連結起來。按照中序遍歷的順序,當我們遍歷轉換到根結點時,它的左子樹已經轉換成一個排序的連結串列了,並且處在連結串列中的最後一個結點是當前值最大的結點。接著我們去遍歷轉換右子樹,並把根結點和右子樹中最小的結點連結起來。左、右子樹的轉換方法相同,很自然地想到可以用遞迴去做。

    public BinaryTreeNode convert(BinaryTreeNode root){  
        BinaryTreeNode node = null;  
        convert(root,node);  
        while(node != null && node.leftNode != null){  
            node = node.leftNode;  
        }  
        return node;  
    }  
    public void convert(BinaryTreeNode root,BinaryTreeNode lastNode){  
        if(root == null)  
            return;  
        BinaryTreeNode current = root;  
        if(current.leftNode != null)  
            convert(current.leftNode,lastNode);  
        current.leftNode = lastNode;  
        if(lastNode != null)  
            lastNode.rightNode = current;  
        if(current.rightNode != null)  
            convert(current.rightNode,lastNode);  
    }