二叉树的遍历(递归与非递归)

9 篇文章 0 订阅
5 篇文章 0 订阅

二叉树的遍历

1.前序遍历

根左右

非递归法

箭头序号对应访问步骤

 

打印结果:A    B    D    E    C    F

/**
     * 前序遍历 - 递归
     * @param treeNode
     */
    public static void rePreOrderTraversal(TreeNode treeNode) {
        System.out.print(treeNode.value + "\t");
        if(treeNode.letf != null) {
            rePreOrderTraversal(treeNode.letf);
        }
        if(treeNode.right != null) {
            rePreOrderTraversal(treeNode.right);
        }

    }

    /**
     * 前序遍历 - 非递归 - 栈
     * @param treeNode
     */
    public static void preOrderTraversal(TreeNode treeNode) {
        // 利用栈存储路径 便于寻找双亲节点
        Stack<TreeNode> stack = new Stack<>();
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                System.out.print(treeNode.value + "\t");
                stack.push(treeNode);
                treeNode = treeNode.letf;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.right;
            }
        }
    }

2.中序遍历

左根右

非递归法

打印结果:D    B    E    A    C    F

/**
     * 中序遍历 - 递归
     * @param treeNode
     */
    public static void reInOrderTraversal(TreeNode treeNode) {
        if (treeNode.letf != null) {
            reInOrderTraversal(treeNode.letf);
        }
        System.out.print(treeNode.value + "\t");
        if (treeNode.right != null) {
            reInOrderTraversal(treeNode.right);
        }
    }

    /**
     * 中序遍历 - 非递归 - 栈
     * @param treeNode
     */
    public static void inOrderTraversal(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                stack.push(treeNode);
                treeNode = treeNode.letf;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                System.out.print(treeNode.value + "\t");
                treeNode = treeNode.right;
            }
        }
    }

 

3.后序遍历

左右根

非递归法-双栈法

后序遍历的方式是“左右根”如果我们可以做到“根右左”再逆序(栈)打印即可

类比前序的“根左右”

打印结果:D    E    B    F    C    A

/**
     * 后序遍历 - 递归
     * @param treeNode
     */
    public static void rePostOrderTraversal(TreeNode treeNode) {
        if (treeNode.letf != null) {
            rePostOrderTraversal(treeNode.letf);
        }
        if (treeNode.right != null) {
            rePostOrderTraversal(treeNode.right);
        }
        System.out.print(treeNode.value + "\t");
    }
    /**
     * 后序遍历 - 非递归 - 双栈
     * @param treeNode
     */
    public static void postOrderTraversal(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        Stack<TreeNode> res = new Stack<>();// 存放"根右左"的遍历结果栈
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                stack.push(treeNode);
                res.push(treeNode);
                treeNode = treeNode.right;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.letf;
            }
        }
        while (!res.isEmpty()) {
            System.out.print(res.pop().value + "\t");
        }
    }

 

总结:

非递归法的遍历仅仅在打印(访问)根节点阶段略有不同

前序:入栈即打印

中序:出栈才打印

后序:入栈也入逆序栈

4.层序遍历(层次遍历)

利用队列

(1)将根节点入队;

(2)访问队首,如果队首有左右孩子,就依次将左右孩子入队,队首出队(打印);

(3)循环(2)直到队空;

/**
     * 层次遍历 - 队列
     * @param treeNode
     */
    public static void levelOrderTraversal(TreeNode treeNode) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(treeNode);
        while (!queue.isEmpty()) {
            TreeNode head = queue.poll();// 获取队首元素
            if (head.letf != null) {
                queue.offer(head.letf);
            }
            if (head.right != null) {
                queue.offer(head.right);
            }
            System.out.print(head.value + "\t");
        }
        System.out.println();
    }

代码汇总

package com.tree;


import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

/**
 * @program: DataStructures
 * @description: 二叉树
 * @author: XuDeming
 * @date: 2020-01-02 10:17:01
 **/
public class BinaryTreeTraversalDemo {
    public static void main(String[] args) {

        TreeNode root = new TreeNode("A");
        TreeNode node2 = new TreeNode("B");
        TreeNode node3 = new TreeNode("C");
        TreeNode node4 = new TreeNode("D");
        TreeNode node5 = new TreeNode("E");
        TreeNode node6 = new TreeNode("F");

        root.letf = node2;
        root.right = node3;
        node2.letf = node4;
        node2.right = node5;
        node3.right = node6;

        System.out.println("递归方式");
        if (root != null) {
            rePreOrderTraversal(root);
            System.out.println();
            reInOrderTraversal(root);
            System.out.println();
            rePostOrderTraversal(root);
            System.out.println();
        }
        System.out.println("----------------------");
        System.out.println("非递归方式");
        preOrderTraversal(root);
        System.out.println();
        inOrderTraversal(root);
        System.out.println();
        postOrderTraversal(root);
        System.out.println();
        System.out.println("----------------------");
        System.out.println("层次遍历");
        levelOrderTraversal(root);

    }

    /**
     * 前序遍历 - 递归
     * @param treeNode
     */
    public static void rePreOrderTraversal(TreeNode treeNode) {
        System.out.print(treeNode.value + "\t");
        if(treeNode.letf != null) {
            rePreOrderTraversal(treeNode.letf);
        }
        if(treeNode.right != null) {
            rePreOrderTraversal(treeNode.right);
        }

    }

    /**
     * 前序遍历 - 非递归 - 栈
     * @param treeNode
     */
    public static void preOrderTraversal(TreeNode treeNode) {
        // 利用栈存储路径 便于寻找双亲节点
        Stack<TreeNode> stack = new Stack<>();
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                System.out.print(treeNode.value + "\t");
                stack.push(treeNode);
                treeNode = treeNode.letf;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.right;
            }
        }
    }

    /**
     * 中序遍历 - 递归
     * @param treeNode
     */
    public static void reInOrderTraversal(TreeNode treeNode) {
        if (treeNode.letf != null) {
            reInOrderTraversal(treeNode.letf);
        }
        System.out.print(treeNode.value + "\t");
        if (treeNode.right != null) {
            reInOrderTraversal(treeNode.right);
        }
    }

    /**
     * 中序遍历 - 非递归 - 栈
     * @param treeNode
     */
    public static void inOrderTraversal(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                stack.push(treeNode);
                treeNode = treeNode.letf;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                System.out.print(treeNode.value + "\t");
                treeNode = treeNode.right;
            }
        }
    }
    /**
     * 后序遍历 - 递归
     * @param treeNode
     */
    public static void rePostOrderTraversal(TreeNode treeNode) {
        if (treeNode.letf != null) {
            rePostOrderTraversal(treeNode.letf);
        }
        if (treeNode.right != null) {
            rePostOrderTraversal(treeNode.right);
        }
        System.out.print(treeNode.value + "\t");
    }
    /**
     * 后序遍历 - 非递归 - 双栈
     * @param treeNode
     */
    public static void postOrderTraversal(TreeNode treeNode) {
        Stack<TreeNode> stack = new Stack<>();
        Stack<TreeNode> res = new Stack<>();// 存放"根右左"的遍历结果栈
        while (treeNode != null || !stack.isEmpty()) {
            while (treeNode != null) {
                stack.push(treeNode);
                res.push(treeNode);
                treeNode = treeNode.right;
            }
            if (!stack.isEmpty()) {
                treeNode = stack.pop();
                treeNode = treeNode.letf;
            }
        }
        while (!res.isEmpty()) {
            System.out.print(res.pop().value + "\t");
        }
    }

    /**
     * 层次遍历 - 队列
     * @param treeNode
     */
    public static void levelOrderTraversal(TreeNode treeNode) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(treeNode);
        while (!queue.isEmpty()) {
            TreeNode head = queue.poll();// 获取队首元素
            if (head.letf != null) {
                queue.offer(head.letf);
            }
            if (head.right != null) {
                queue.offer(head.right);
            }
            System.out.print(head.value + "\t");
        }
        System.out.println();
    }

}

// 节点
class TreeNode {

    String value;
    TreeNode letf;
    TreeNode right;

    public TreeNode(String value) {
        this.value = value;
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值