中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么實現python二叉樹的遍歷分析

發布時間:2021-12-13 17:35:07 來源:億速云 閱讀:122 作者:柒染 欄目:云計算

這篇文章給大家介紹怎么實現python二叉樹的遍歷分析,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

/**
 * 先序遍歷:按照“根左右”的順序,先遍歷根節點,再遍歷左子樹,再遍歷右子樹
 * 中序遍歷:按照“左根右“的順序,先遍歷左子樹,再遍歷根節點,最后遍歷右子樹
 * 后續遍歷:按照“左右根”的順序,先遍歷左子樹,再遍歷右子樹,最后遍歷根節點
 * <p>
 * 說明:
 *		1)這里的'先/中/后'是指每次遍歷的時候,根節點被遍歷的順序。
 * 		2)每個節點都可以看做一個跟節點。
 * 		3)遍歷的時候,我們會將當前節點作為一個根節點來看待。
 */

public class BinaryTree {

Integer value;
BinaryTree leftChild;
BinaryTree rightChild;

public BinaryTree(Integer value, BinaryTree leftChild, BinaryTree rightChild) {
    this.value = value;
    this.leftChild = leftChild;
    this.rightChild = rightChild;
}


// 存放遍歷后的節點
static ArrayList<BinaryTree> list = new ArrayList<BinaryTree>();

/**
 * 先序遍歷
 */
public static void preOrder(BinaryTree root) {

    if (root == null) return;

    list.add(root);                 // 1.將當前節點(根節點)存入list
    if (root.leftChild != null) {   // 2.當前節點的左子樹不為空時,繼續往左找
        preOrder(root.leftChild);
    }                               // 3.當前節點的左子樹為空時,說明根節點和左孩子已經遍歷完畢了,則接下來遍歷右孩子

    if (root.rightChild != null) {
        preOrder(root.rightChild);
    }
}

/**
 * 中序遍歷
 */
public static void inOrder(BinaryTree root) {

    if (root == null) return;

    if (root.leftChild != null) {
        inOrder(root.leftChild);
    }
    list.add(root);
    if (root.rightChild != null) {
        inOrder(root.rightChild);
    }
}

/**
 * 后序遍歷
 */
public static void postOrder(BinaryTree root) {

    if (root == null) return;

    if (root.leftChild != null) {
        postOrder(root.leftChild);
    }
    if (root.rightChild != null) {
        postOrder(root.rightChild);
    }
    list.add(root);

}


/**
 * 先序遍歷 非遞歸
 *
 * [@param](https://my.oschina.net/u/2303379) root
 */
public static void preOrderNonRecursion(BinaryTree root) {

    if (root == null) return;

    Stack<BinaryTree> stack = new Stack<BinaryTree>();

    BinaryTree currentNode = root;

    while (!stack.empty() || currentNode != null) {

        while (currentNode != null) {
            list.add(currentNode);
            stack.push(currentNode);                // 1.將當前節點(根節點)存在棧中
            currentNode = currentNode.leftChild;    // 2.當前節點的左子樹不為空時,將當前節點的左子樹作為根節點,繼續執行循環。 注:這里與遞歸式的先序遍歷類似。
        }                                           // 3.當前節點的左子樹為空時,說明根節點和左孩子已經遍歷完畢了,則接下來遍歷右孩子

        if (!stack.empty()) {
            currentNode = stack.pop();
            currentNode = currentNode.rightChild;
        }

    }
}

/**
 * 中序遍歷 非遞歸
 *
 * [@param](https://my.oschina.net/u/2303379) root
 */
public static void inOrderNonRecursion(BinaryTree root) {

    if (root == null) return;

    Stack<BinaryTree> stack = new Stack<BinaryTree>();

    BinaryTree currentNode = root;

    while (!stack.empty() || currentNode != null) {

        while (currentNode != null) {
            stack.push(currentNode);
            currentNode = currentNode.leftChild;
        }

        // 當root為空時,說明已經到達左子樹最下邊,這時需要出棧了
        if (!stack.empty()) {
            currentNode = stack.pop();
            list.add(currentNode);
            currentNode = currentNode.rightChild;
        }

    }
}

/**
 * 后序遍歷 非遞歸
 *  要點:
 *      1)后序遍歷需要判斷上次訪問的節點是位于左子樹,還是右子樹。
 *      2)  若是位于左子樹,則需跳過根節點,先進入右子樹,再回頭訪問根節點;
 *      3)  若是位于右子樹,則直接訪問根節點。
 *
 * [@param](https://my.oschina.net/u/2303379) root
 */
public static void postOrderNonRecursion(BinaryTree root) {

    if (root == null) return;

    Stack<BinaryTree> stack = new Stack<BinaryTree>();

    BinaryTree currentNode = root;   // 當前訪問的節點
    BinaryTree lastVisitNode = null; // 上次訪問的節點

    // 把currentNode移到當前節點的左子樹的最左邊
    while (currentNode != null) {
        stack.push(currentNode);
        currentNode = currentNode.leftChild;
    }

    while (!stack.empty()) {
        currentNode = stack.pop();

        // 后續遍歷中,一個根節點被訪問的前提是:當前節點(可以看成根節點)無右子樹 或 當前節點的右子樹剛剛被訪問過。
        if (currentNode.rightChild != null && currentNode.rightChild != lastVisitNode) {

            stack.push(currentNode); // 當前節點的右子樹不為空且沒有被訪問過,故根節點(當前節點)再次入棧。

            // 進入右子樹,把currentNode移到當前節點的右子樹的最左邊
            currentNode = currentNode.rightChild;
            while (currentNode != null) {
                stack.push(currentNode);
                currentNode = currentNode.leftChild;
            }
        } else {
            // 訪問
            list.add(currentNode);
            lastVisitNode = currentNode;
        }
    }

}


/**
 * 返回當前數的深度
 * 1.如果一棵樹只有一個結點,它的深度為1
 * 2.如果根結點只有左子樹而沒有右子樹,那么樹的深度是其左子樹的深度加1
 * 3.如果根結點只有右子樹而沒有左子樹,那么樹的深度應該是其右子樹的深度加1
 * 4.如果既有右子樹又有左子樹,那該樹的深度就是其左、右子樹深度的較大值加1
 *
 * [@param](https://my.oschina.net/u/2303379) root
 * [@return](https://my.oschina.net/u/556800)
 */
public static int getTreeDepth(BinaryTree root) {
    int left = 0, right = 0;

    if (root.leftChild == null && root.rightChild == null) {
        return 1;
    }
    if (root.leftChild != null) {
        left = getTreeDepth(root.leftChild);
    }
    if (root.rightChild != null) {
        right = getTreeDepth(root.rightChild);
    }
    return left > right ? left + 1 : right + 1;
}

/**
 * 樹的初始化:先從葉子節點開始,由葉到根
 */
public static BinaryTree getBinaryTree() {

    BinaryTree leaf1 = new BinaryTree(11, null, null);
    BinaryTree leaf2 = new BinaryTree(12, null, null);
    BinaryTree firstMidNode1 = new BinaryTree(21, leaf1, leaf2);

    BinaryTree leaf3 = new BinaryTree(13, null, null);
    BinaryTree leaf4 = new BinaryTree(14, null, null);
    BinaryTree firstMidNode2 = new BinaryTree(22, leaf3, leaf4);

    BinaryTree secondMidNode1 = new BinaryTree(31, firstMidNode1, firstMidNode2);
    BinaryTree leaf5 = new BinaryTree(32, null, null);

    BinaryTree root = new BinaryTree(41, secondMidNode1, leaf5);
    return root;
}

public static void main(String[] args) {

    BinaryTree root = getBinaryTree();
//        preOrder(root);
//        inOrder(root);
//        postOrder(root);
           preOrderNonRecursion(root);
//        inOrderNonRecursion(root);
//        postOrderNonRecursion(root);

    ArrayList<Integer> resultList = new ArrayList<Integer>();
    for (BinaryTree node : list) {
        resultList.add(node.value);
    }
    System.out.println("遍歷的結果:" + resultList);
    System.out.println("樹的高度:" + getTreeDepth(root));

 }
}

關于怎么實現python二叉樹的遍歷分析就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淮北市| 屏南县| 平昌县| 清徐县| 临江市| 伊春市| 竹北市| 潮州市| 桐梓县| 广德县| 疏附县| 金溪县| 定州市| 英山县| 霍林郭勒市| 连州市| 萝北县| 花垣县| 剑川县| 怀仁县| 乐清市| 周至县| 永登县| 宿松县| 正阳县| 四会市| 左贡县| 耒阳市| 绩溪县| 长丰县| 民乐县| 独山县| 栾川县| 齐河县| 沁水县| 安多县| 秭归县| 门头沟区| 视频| 攀枝花市| 大丰市|