java遍历二叉树组

<code class="hljs java has-numbering"><span class="hljs-javadoc">/**
 *<span class="hljs-javadoctag"> @Date</span> 
 *
 *<span class="hljs-javadoctag"> @author</span>
 *
 */</span>
<span class="hljs-keyword">package</span> tree;

<span class="hljs-keyword">import</span> java.util.Stack;

<span class="hljs-javadoc">/**
 *<span class="hljs-javadoctag"> @author</span> 郭 璞 <br>
 *         二叉树的先序,中序,以及后序,递归以及非递归的实现
 *
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FullScan</span> {</span>

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span>(String[] args) {
        Node head = createTree();
        <span class="hljs-comment">// recurseFront(head);</span>
        <span class="hljs-comment">// recurseMid(head);</span>
        recurseEnd(head);
        <span class="hljs-comment">// front(head);</span>
        <span class="hljs-comment">// mid(head);</span>
        endWith2Stack(head);
        endWithOneStack(head);
    }

    <span class="hljs-javadoc">/**
     * 非递归实现的二叉树后序遍历<br>
     * 借助于一个栈进行实现
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">endWithOneStack</span>(Node head) {
        System.out.println();
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span>;
        } <span class="hljs-keyword">else</span> {
            Stack<Node> stack = <span class="hljs-keyword">new</span> Stack<Node>();
            stack.push(head);
            <span class="hljs-comment">// 该节点代表已经打印过的节点,待会会及时的进行更新</span>
            Node printedNode = <span class="hljs-keyword">null</span>;
            <span class="hljs-keyword">while</span> (!stack.isEmpty()) {
                <span class="hljs-comment">// 获取 栈顶的元素的值,而不是pop掉栈顶的值</span>
                head = stack.peek();
                <span class="hljs-comment">// 如果当前栈顶元素的左节点不为空,左右节点均未被打印过,说明该节点是全新的,所以压入栈中</span>
                <span class="hljs-keyword">if</span> (head.getLeft() != <span class="hljs-keyword">null</span> && printedNode != head.getLeft() && printedNode != head.getRight()) {
                    stack.push(head.getLeft());
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (head.getRight() != <span class="hljs-keyword">null</span> && printedNode != head.getRight()) {
                    <span class="hljs-comment">// 第一层不满足,则说明该节点的左子树已经被打印过了。如果栈顶元素的右节点未被打印过,则将右节点压入栈中</span>
                    stack.push(head.getRight());
                } <span class="hljs-keyword">else</span> {
                    <span class="hljs-comment">// 上面两种情况均不满足的时候则说明左右子树均被打印过,此时只需要弹出栈顶元素,打印该值即可</span>
                    System.out.println(<span class="hljs-string">"当前值为:"</span> + stack.pop().getValue());
                    <span class="hljs-comment">// 记得实时的更新打印过的节点的值</span>
                    printedNode = head;
                }
            }
        }
    }

    <span class="hljs-javadoc">/**
     * 非递归实现的二叉树的后序遍历<br>
     * 借助于两个栈来实现
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">endWith2Stack</span>(Node head) {
        System.out.println();
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span>;
        } <span class="hljs-keyword">else</span> {
            Stack<Node> stack1 = <span class="hljs-keyword">new</span> Stack<Node>();
            Stack<Node> stack2 = <span class="hljs-keyword">new</span> Stack<Node>();

            stack1.push(head);
            <span class="hljs-comment">// 对每一个头结点进行判断,先将头结点放入栈2中,然后依次将该节点的子元素放入栈1.顺序为left-->right。便是因为后序遍历为“左右根”</span>
            <span class="hljs-keyword">while</span> (!stack1.isEmpty()) {
                head = stack1.pop();
                stack2.push(head);
                <span class="hljs-keyword">if</span> (head.getLeft() != <span class="hljs-keyword">null</span>) {
                    stack1.push(head.getLeft());
                }

                <span class="hljs-keyword">if</span> (head.getRight() != <span class="hljs-keyword">null</span>) {
                    stack1.push(head.getRight());
                }
            }

            <span class="hljs-comment">// 直接遍历输出栈2,即可实现后序遍历的节点值的输出</span>
            <span class="hljs-keyword">while</span> (!stack2.isEmpty()) {
                System.out.println(<span class="hljs-string">"当前节点的值:"</span> + stack2.pop().getValue());
            }
        }
    }

    <span class="hljs-javadoc">/**
     * 非递归实现的二叉树的中序遍历
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">mid</span>(Node head) {
        System.out.println();
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span>;
        } <span class="hljs-keyword">else</span> {
            Stack<Node> nodes = <span class="hljs-keyword">new</span> Stack<Node>();

            <span class="hljs-comment">// 使用或的方式是因为 第一次的时候战中元素为空,head的非null特性可以保证程序可以执行下去</span>
            <span class="hljs-keyword">while</span> (!nodes.isEmpty() || head != <span class="hljs-keyword">null</span>) {
                <span class="hljs-comment">// 当前节点元素值不为空,则放入栈中,否则先打印出当前节点的值,然后将头结点变为当前节点的右子节点。</span>
                <span class="hljs-keyword">if</span> (head != <span class="hljs-keyword">null</span>) {
                    nodes.push(head);
                    head = head.getLeft();
                } <span class="hljs-keyword">else</span> {
                    Node temp = nodes.pop();
                    System.out.println(<span class="hljs-string">"当前节点的值:"</span> + temp.getValue());
                    head = temp.getRight();
                }
            }

        }
    }

    <span class="hljs-javadoc">/**
     * 非递归实现的二叉树的先序遍历
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">front</span>(Node head) {
        System.out.println();

        <span class="hljs-comment">// 如果头结点为空,则没有遍历的必要性,直接返回即可</span>
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span>;
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-comment">// 初始化用于存放节点顺序的栈结构</span>
            Stack<Node> nodes = <span class="hljs-keyword">new</span> Stack<Node>();
            <span class="hljs-comment">// 先把head节点放入栈中,便于接下来的循环放入节点操作</span>
            nodes.add(head);

            <span class="hljs-keyword">while</span> (!nodes.isEmpty()) {
                <span class="hljs-comment">// 取出栈顶元素,判断其是否有子节点</span>
                Node temp = nodes.pop();

                System.out.println(<span class="hljs-string">"当前节点的值:"</span> + temp.getValue());
                <span class="hljs-comment">// 先放入右边子节点的原因是先序遍历的话输出的时候左节点优先于右节点输出,而栈的特性决定了要先放入右边的节点</span>
                <span class="hljs-keyword">if</span> (temp.getRight() != <span class="hljs-keyword">null</span>) {
                    nodes.push(temp.getRight());
                }
                <span class="hljs-keyword">if</span> (temp.getLeft() != <span class="hljs-keyword">null</span>) {
                    nodes.push(temp.getLeft());
                }
            }
        }
    }

    <span class="hljs-javadoc">/**
     * 递归实现的先序遍历
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">recurseFront</span>(Node head) {
        System.out.println();

        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>) {
            <span class="hljs-keyword">return</span>;
        }
        System.out.println(<span class="hljs-string">"当前节点值:"</span> + head.getValue());
        recurseFront(head.left);
        recurseFront(head.right);
    }

    <span class="hljs-javadoc">/**
     * 递归实现的中序遍历
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">recurseMid</span>(Node head) {
        System.out.println();
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>)
            <span class="hljs-keyword">return</span>;
        recurseMid(head.getLeft());
        System.out.println(<span class="hljs-string">"当前节点的值:"</span> + head.getValue());
        recurseMid(head.getRight());
    }

    <span class="hljs-javadoc">/**
     * 递归实现的后序遍历递归实现
     * 
     *<span class="hljs-javadoctag"> @param</span> head
     */</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">recurseEnd</span>(Node head) {
        System.out.println();
        <span class="hljs-keyword">if</span> (head == <span class="hljs-keyword">null</span>)
            <span class="hljs-keyword">return</span>;
        recurseEnd(head.getLeft());
        recurseEnd(head.getRight());
        System.out.println(<span class="hljs-string">"当前节点的值为:"</span> + head.getValue());
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Node <span class="hljs-title">createTree</span>() {
        <span class="hljs-comment">// 初始化节点</span>
        Node head = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">1</span>);
        Node headLeft = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">2</span>);
        Node headRight = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">3</span>);
        Node headLeftLeft = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">4</span>);
        Node headLeftRigth = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">5</span>);
        Node headRightLeft = <span class="hljs-keyword">new</span> Node(<span class="hljs-number">6</span>);
        <span class="hljs-comment">// 为head节点 赋予左右值</span>
        head.setLeft(headLeft);
        head.setRight(headRight);

        headLeft.setLeft(headLeftLeft);
        headLeft.setRight(headLeftRigth);
        headRight.setLeft(headRightLeft);

        <span class="hljs-comment">// 返回树根节点</span>
        <span class="hljs-keyword">return</span> head;
    }

}

class Node {
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> value;
    <span class="hljs-keyword">public</span> Node left;
    <span class="hljs-keyword">public</span> Node right;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getValue</span>() {
        <span class="hljs-keyword">return</span> value;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setValue</span>(<span class="hljs-keyword">int</span> value) {
        <span class="hljs-keyword">this</span>.value = value;
    }

    <span class="hljs-keyword">public</span> Node <span class="hljs-title">getLeft</span>() {
        <span class="hljs-keyword">return</span> left;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setLeft</span>(Node left) {
        <span class="hljs-keyword">this</span>.left = left;
    }

    <span class="hljs-keyword">public</span> Node <span class="hljs-title">getRight</span>() {
        <span class="hljs-keyword">return</span> right;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setRight</span>(Node right) {
        <span class="hljs-keyword">this</span>.right = right;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Node</span>() {
    }

    <span class="hljs-keyword">public</span> <span class="hljs-title">Node</span>(<span class="hljs-keyword">int</span> value) {
        <span class="hljs-keyword">this</span>.value = value;
    }
}</code><div style="display: none;" class="save_code tracking-ad" data-mod="popu_249"><a target=_blank target="_blank" href="javascript:;"><img src="http://static.blog.csdn.net/images/save_snippets.png" alt="" /></a></div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值