二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现

什么是树?什么是二叉树?
树:除了根节点之外的所有节点都有且只有一个父节点,根节点没有父节点;除了叶结点以外的所有节点,都有一个或多个子节点,叶结点没有子节点。
二叉树:是树的一种特殊结构,在二叉树中,每个节点最多只能有两个子节点。
二叉树的遍历方式:
1、先序遍历(递归、非递归);
2、中序遍历(递归、非递归);
3、后序遍历(递归、非递归);
4、层次遍历。

建树、遍历代码:

public class BinaryTree<E> {

    private static class Node<E>{
        public E value; //节点值
        public Node<E> left; //左节点
        public Node<E> right;//右节点

        public Node(E value) {
            this.value = value;
            this.left = null;
            this.right = null;
        }
    }

    public static List<Node<Integer>> nodeList = null;//用于存储二叉树的节点
    /**
     * 创建数组
     * @param length
     * @return
     */
    public int[] createArray(int length){
        int[] array = new int[length];
        for (int i = 0; i < array.length; i++) {
            array[i] = (int)(Math.random() * 100);
        }
        return array;
    }

    /**
     * 创建二叉树
     */
    public void createBinaryTree(int nodeNum){
        nodeList = new ArrayList<Node<Integer>>();
        int[] array = createArray(nodeNum);
        for(int i : array){
            System.out.print(i + " ");
        }
        System.out.println();
        for (int i = 0; i < array.length; i++) {
             Node<Integer> temp = new Node<Integer>(array[i]);
             nodeList.add(temp);
        }
        for (int parentIndex = 0; parentIndex < array.length/2 - 1; parentIndex++) {
            //父节点
            Node<Integer> parentNode = nodeList.get(parentIndex);
            //左节点
            parentNode.left = nodeList.get(parentIndex * 2 + 1);
            //右节点
            parentNode.right = nodeList.get(parentIndex * 2 + 2);

            int lastParentIndex = array.length/2 - 1;
            Node<Integer> lastParentNode = nodeList.get(lastParentIndex);
            lastParentNode.left = nodeList.get(lastParentIndex * 2 + 1);
            //总节点数为基数,最后一个父节点才有右孩子
            if (array.length % 2 == 1) {
                lastParentNode.right = nodeList.get(lastParentIndex * 2 + 2);
            }
        }

    }

    /**
     * 二叉树先序遍历(递归)
     * @param parentNode
     */
    public void BinaryTreePreOrder(Node<E> parentNode){
        if (parentNode == null) {
            return;
        }
        System.out.print(parentNode.value + " ");
        BinaryTreePreOrder(parentNode.left);
        BinaryTreePreOrder(parentNode.right);
    }
    /**
     * 二叉树先序遍历(循环)
     * @param rootNode
     */
    public void BinaryTreePreOrder_loop(Node<E> rootNode){
        Stack<Node<E>> stack = new Stack<Node<E>>();
        Node<E> cur = rootNode;
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                System.out.print(cur.value + " ");
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            cur = cur.right;
        }
    }

    /**
     * 二叉树中序遍历(递归)
     * @param parentNode
     */
    public void BinaryTreeMidOrder(Node<E> parentNode){
        if (parentNode == null) {
            return;
        }
        BinaryTreeMidOrder(parentNode.left);
        System.out.print(parentNode.value + " ");
        BinaryTreeMidOrder(parentNode.right);
    }

    /**
     * 二叉树中序遍历(循环)
     * @param rootNode
     */
    public void BinaryTreeMidOrder_loop(Node<E> rootNode){
        Stack<Node<E>> stack = new Stack<Node<E>>();
        Node<E> cur = rootNode;
        while(cur != null || !stack.isEmpty()){
            while(cur != null){
                stack.push(cur);
                cur = cur.left;
            }
            cur = stack.pop();
            System.out.print(cur.value + " ");
            cur = cur.right;
        }
    }
    /**
     * 二叉树后序遍历(递归)
     * @param parentNode
     */
    public void BinaryTreePostOrder(Node<E> parentNode){
        if (parentNode == null) {
            return;
        }
        BinaryTreePostOrder(parentNode.left);
        BinaryTreePostOrder(parentNode.right);
        System.out.print(parentNode.value + " ");
    }

    /**
     * 二叉树后序遍历(非递归)
     * 先处理左右子树,再处理根
     * @param rootNode
     */
    public void BinaryTreePostOrder_loop(Node<E> rootNode){
        Stack<Node<E>> stack = new Stack<Node<E>>();
        //使用map来标记已经访问过的节点
        Map<Node<E>, Boolean> nodeMap = new HashMap<Node<E>, Boolean>();
        stack.push(rootNode);
        while(!stack.isEmpty()){
            Node<E> temp = stack.peek();
            //获取左子树的左节点
            if (temp.left != null && !nodeMap.containsKey(temp.left)) {
                temp = temp.left;
                while(temp != null){
                    stack.push(temp);
                    temp = temp.left;
                }
                continue;
            }
            //获取右节点
            if (temp.right != null && !nodeMap.containsKey(temp.right)) {
                stack.push(temp.right);
                continue;
            }
            Node<E> cur = stack.pop();
            System.out.print(cur.value + " ");
            nodeMap.put(cur, true);
        }
    }

    /**
     * 二叉树层次遍历
     * @param rootNode
     */
    public void BinaryTreeLevelOrder(Node<E> rootNode){
        //使用队列来实现遍历
        Queue<Node<E>> queue = new LinkedList<Node<E>>();
        queue.add(rootNode);
        while(!queue.isEmpty()){
            Node<E> parentNode = queue.poll();
            System.out.print(parentNode.value + " ");
            if (parentNode.left != null) {
                queue.add(parentNode.left);
            }
            if (parentNode.right != null) {
                queue.add(parentNode.right);
            }
        }
    }
    public static void main(String[] args) {
        BinaryTree<Integer> tree = new BinaryTree<Integer>();
        System.out.println("遍历前数组:");
        tree.createBinaryTree(11);
        Node<Integer> rootNode = nodeList.get(0);
        System.out.println("先序遍历(递归):");
        tree.BinaryTreePreOrder(rootNode);
        System.out.println();
        System.out.println("先序遍历(非递归):");
        tree.BinaryTreePreOrder_loop(rootNode);
        System.out.println();
        System.out.println("中序遍历(递归):");
        tree.BinaryTreeMidOrder(rootNode);
        System.out.println();
        System.out.println("中序遍历(非递归):");
        tree.BinaryTreeMidOrder_loop(rootNode);
        System.out.println();
        System.out.println("后序遍历(递归):");
        tree.BinaryTreePostOrder(rootNode);
        System.out.println();
        System.out.println("后序遍历(非递归):");
        tree.BinaryTreePostOrder_loop(rootNode);
        System.out.println();
        System.out.println("层次遍历:");
        tree.BinaryTreeLevelOrder(rootNode);
    }
}

测试结果:

遍历前数组:
39 21 69 6 78 21 83 53 69 52 85 
先序遍历(递归):
39 21 6 53 69 78 52 85 69 21 83 
先序遍历(非递归):
39 21 6 53 69 78 52 85 69 21 83 
中序遍历(递归):
53 6 69 21 52 78 85 39 21 69 83 
中序遍历(非递归):
53 6 69 21 52 78 85 39 21 69 83 
后序遍历(递归):
53 69 6 52 85 78 21 21 83 69 39 
后序遍历(非递归):
53 69 6 52 85 78 21 21 83 69 39 
层次遍历:
39 21 69 6 78 21 83 53 69 52 85 
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值