バイナリツリートラバーサルと非再帰的、再帰/トラバースレベル

バイナリツリートラバーサル

順トラバーサル、後順とレベルトラバーサルで古典的なバイナリツリートラバーサル4、先行順走査、。

ここで、前、間およびプリント注文横断ノードのその左及び右サブツリーのノードによって表される配列ました。

 

その後、ツリー内の任意のノード、このノードの最初の印刷、および印刷することがサブツリーを左に、そして最終的にその右のサブツリーを印刷する、という先行順走査手段。

予約限定手段は、ツリー内の任意のノードのために、最初にその左部分木を印刷し、それ自体を印刷し、そして最後にその右のサブツリーを印刷します。

ツリー内の任意のノードのために、最初にその左部分木を印刷して、それを右のサブツリーを印刷し、そして最終的にはノード自体を印刷し、後順の手段。

 

その後の前にDFS(深さ優先アルゴリズム)の考えで

 

 

実際には、順序トラバーサル中と後のバイナリツリーの前には、再帰的なプロセスです。

前順走査は、実際には、ルートノードを印刷する最初で、その後、再帰的に左のサブツリーを印刷し、最終的には右のサブツリーが再帰的に印刷します。 

前序遍历的递推公式:
preOrder(r) = print r->preOrder(r.left)->preOrder(r.right)

中序遍历的递推公式:
inOrder(r) = inOrder(r.left)->print r->inOrder(r.right)

后序遍历的递推公式:
postOrder(r) = postOrder(r.left)->postOrder(r.right)->print r

 

リカーシブ

    /**
     * 先序遍历
     */
    public static void preOrder(Node root) {
        if (root == null) {
            return;
        }
        System.out.print(root.value + " -> ");
        preOrder(root.left);
        preOrder(root.right);
    }

    /**
     * 中序遍历
     */
    public static void inOrder(Node root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        System.out.print(root.value + " -> ");
        inOrder(root.right);
    }

    /**
     * 后序遍历
     */
    public static void postOrder(Node root) {
        if (root == null) {
            return;
        }
        postOrder(root.left);
        postOrder(root.right);
        System.out.print(root.value + " ->  ");
    }

非再帰

スタック自体は再帰的な実装であると、非再帰的な実装はまた、本質的に、我々は実際になって「マニュアル再帰」を達成するためにスタックする必要があります

    /**
     * 前序遍历
     */

    public static void preOrder2(Node root) {
        if (root == null) {
            return;
        }
        Stack<Node> s = new Stack<>();
        s.push(root);
        Node curNode;
        while (!s.isEmpty()) {
            curNode = s.pop();
            System.out.print(curNode.data + "->");
            // 栈先进后出,所以先加入右侧节点,这样输出的时候,先输出左侧节点
            if (curNode.right != null) {
                s.push(curNode.right);
            }
            if (curNode.left != null) {
                s.push(curNode.left);
            }
        }
    }


    /**
     * 中序遍历
     */

    public static void inOrder2(Node root) {
        if (root == null) {
            return;
        }
        Stack<Node> s = new Stack<>();
        Node curNode = root;
        while (!s.isEmpty() || curNode != null) {
            // 入栈所有左节点并输出左节点
            while (curNode != null) {
                s.push(curNode);
                curNode = curNode.left;
            }

            // 弹出左节点
            curNode = s.pop();
            System.out.print(curNode.data + "->");
            // 弹出后,指向当前节点的右节点
            curNode = curNode.right;
        }
    }

     /**
     * 后序遍历
     */
    public static void postOrder2(Node root) {
        if (root == null) {
            return;
        }

        Stack<Node> s1 = new Stack<>();
        Stack<Node> s2 = new Stack<>();

        s1.push(root);

        Node curNode;
        while (!s1.isEmpty()) {

            curNode = s1.pop();
            // 中、右、左顺序压入栈中
            s2.push(curNode);

            // 压入s1为先左后右,保证中、右、左顺序压入s2中
            if (curNode.left != null) {
                s1.push(curNode.left);
            }
            if (curNode.right != null) {
                s1.push(curNode.right);
            }
        }
        while (!s2.isEmpty()) {
            System.out.print(s2.pop().data + "->");
        }

    }

レベルをトラバース

レベルトラバーサルBFS(幅優先アルゴリズム)思考。

一般的なキューによって達成レベルのバイナリツリートラバーサル。

 

レベルトラバースステップは以下のとおりです。

ノード1.が空でない場合、最初のノードがキューに追加されます

チームノードのうち2は、子供が空のままにされていない場合、ノードは、子どもたちがキューに追加、または何もしないことが残っていました。同様に右の子

3.上記の操作は、キューが空になるまで繰り返され、終了レベルを横切ります

 

    public static void LevelTraversal(Node root) {
        if (root == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<Node>();
        Node curNode = null;
        queue.offer(root);//将根节点入队
        while (!queue.isEmpty()) {
            curNode = queue.poll();//出队队头元素并访问
            System.out.print(curNode.data + "->");
            if (curNode.left != null)//如果当前节点的左节点不为空入队
            {
                queue.offer(curNode.left);
            }
            if (curNode.right != null)//如果当前节点的右节点不为空,把右节点入队
            {
                queue.offer(curNode.right);
            }
        }
    }

 

公開された113元の記事 ウォン称賛25 ビュー30000 +

おすすめ

転載: blog.csdn.net/qq_42006733/article/details/104589720