java数组转二叉树-前序遍历-中序遍历-后序遍历-层序遍历

5 篇文章 0 订阅

二叉树定义:

二叉树是每个节点最多有两个子树的树结构。
它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。

这里写图片描述
图1-1

二叉树按照其子树的分布状态,又出现两个特殊的二叉树:满二叉树,完全二叉树。

满二叉树:所有的分支结点都存在左子树和右子树,并且所有的叶子结点都在同一层上,这样就是满二叉树。满二叉树见下图:
这里写图片描述
图1-2
完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。满二叉树必须是完全二叉树,反过来不一定成立。完全二叉树见下图:

这里写图片描述
图1-3

二叉树的性质

一般二叉树:
*第n层最多有2^(n-1)个节点。*
深度为k的二叉树 最多有节点 2^k - 1个。
*对于任何一颗二叉树 如果其叶节点有n个 度为2的非叶节点有m个 则有 n = m + 1。*
具有n个节点的完全二叉树的高度为 [lgN + 1](log以2为底) [X]表示不大于X的最大整数。
一个有n个节点的二叉树 (lgN+1 2为底) 按层次对节点进行编号(从上到下 从左到右)对任意节点有。
满二叉树:
如果对满二叉树按1-n编号,设某节点为n,那么该满二叉树的左孩子节点为2*n+1,右孩子节点为2*i+2。
如果对满二叉树按1-n编号,设总节点为n个,可以得出最后一个非叶子节点为n/2 向下取整

二叉树的遍历

1、深度优先:
前序遍历:先根节点,再遍历左孩子节点,再遍历右孩子节点。利用递归实现。(图1-3,遍历后:0-1-3-7-8-4-2-5-6)
中序遍历:先左孩子节点,再遍历根节点,再遍历右孩子节点。利用递归实现。(图1-3,遍历后:7-3-8-1-4-0-5-2-6)
后序遍历:先左孩子节点,再遍历右孩子节点,再遍历左孩子节点。利用递归实现。(图1-3,遍历后:7-8-3-4-1-5-6-2-0)
注意:前三种遍历是以深度优先,比如前序遍历,同一层节点,左孩子没有遍历结束,不会遍历右孩子。可以利用栈模仿递归,实现这三种遍历
2、广度优先:
层序遍历,将二叉树按照层,逐层遍历数据,借助队列(先进先出)实现。(图1-3,遍历后:0-1-2-3-4-5-6-7-8)

数组转二叉树、二叉树遍历和测试代码如下:

package tree;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

public class BinaryTree {
    public int data;// value
    public static ArrayList<BinaryTree> temps;// 构造二叉树临时数据
    public BinaryTree left = null;// 左子树
    public BinaryTree right = null;// 右子数

    // 数组转二叉树
    public static BinaryTree arraysToTree(int arrays[]) {
        if (arrays.length == 0) {
            return null;
        }
        int length = arrays.length;

        // 生成二叉树节点
        temps = new ArrayList<BinaryTree>(length);
        for (int i = 0; i < length; i++) {
            BinaryTree node = new BinaryTree();
            node.data = arrays[i];
            temps.add(node);

        }
        // 构建二叉树 根节点n[i] 左子树n[i*2+1] 右子树 n[i*2+2]
        for (int i = 0; i < length / 2 - 1; i++) {
            BinaryTree node = temps.get(i);
            node.left = temps.get(2 * i + 1);
            node.right = temps.get(2 * i + 2);

        }
        // 处理最后一个节点
        int lastNode = length / 2 - 1;
        BinaryTree node = temps.get(lastNode);
        // 添加左子树
        node.left = temps.get(lastNode * 2 + 1);

        if (length % 2 != 0) {
            // 当为偶数时,添加右子树
            node.right = temps.get(lastNode * 2 + 2);
        }

        BinaryTree root = temps.get(0);
        temps.clear();
        temps = null;
        return root;

    }

    // 前序遍历打印二叉树
    public static void prOrderTree(BinaryTree node) {
        if (node == null) {
            return;
        }
        System.out.print("\t" + node.data);
        // 左子树
        BinaryTree left = node.left;
        // 打印节点信息
        if (left != null) {
            prOrderTree(left);
        }
        // 右子树
        BinaryTree right = node.right;
        if (right != null) {
            prOrderTree(right);
        }

    }

    // 中序遍历
    public static void inOrderTree(BinaryTree node) {
        if (node == null) {
            return;
        }
        // 左子树
        BinaryTree left = node.left;
        if (left != null) {
            inOrderTree(left);
        }
        // 打印节点信息
        System.out.print("\t" + node.data);
        // 右子树
        BinaryTree right = node.right;
        if (right != null) {
            inOrderTree(right);
        }

    }

    // 后序遍历
    public static void postOrderTree(BinaryTree node) {
        if (node == null) {
            return;
        }
        // 左子树
        BinaryTree left = node.left;
        if (left != null) {
            postOrderTree(left);
        }
        // 右子树
        BinaryTree right = node.right;
        if (right != null) {
            postOrderTree(right);
        }
        // 打印节点信息
        System.out.print("\t" + node.data);

    }

    // 层序遍历
    public static void levelOrderTree(BinaryTree node) {

        if (node == null) {
            return;
        }
        Queue<BinaryTree> queue = new LinkedList<BinaryTree>();// 队列
        queue.offer(node);
        while (!queue.isEmpty()) {

            BinaryTree root = queue.poll();
            // 输出内容
            System.out.print("\t" + root.data);

            // 左子树
            BinaryTree left = root.left;
            if (left != null) {
                queue.offer(left);
            }
            // 右子树
            BinaryTree right = root.right;
            if (right != null) {
                queue.offer(right);
            }

        }

    }

}

// 测试代码

public class Test {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int arrays []=new int [8];
        for(int i =0;i<arrays.length;i++){
            arrays[i]= i;
        }
        BinaryTree binaryTree = BinaryTree.arraysToTree(arrays);
        System.out.println("前序遍历:");
        BinaryTree.prOrderTree(binaryTree);
        System.out.println("\n中序遍历:");
        BinaryTree.inOrderTree(binaryTree);
        System.out.println("\n后序遍历:");
        BinaryTree.postOrderTree(binaryTree);
                System.out.println("\n层序遍历:");
        BinaryTree.levelOrderTree(binaryTree);
    }


}

测试结果:
这里写图片描述

希望对你有所帮助。。。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值