二叉树的定义和Java实现

先放上数据结构中有关树的一些定义:

  1. 节点:节点包括一个数据元素及若干指向其子树的分支

  2. 节点的度:节点所拥有的子树的个数成为该节点的度

  3. 叶节点:度为0的节点称为叶结点

  4. 分支节点:度不为0的节点称为分支节点

  5. 树的度:树中所有节点的度的最大值

  6. 二叉树:是n(n>=0)个有限节点构成的集合。n=0的树称为空二叉树;n=1的树只有一个根结点;
    n>1的二叉树由一个根节点和至多两个互不相交的,分别称为左子树和右子树的子二叉树构成
    二叉树不是有序树,这是因为,二叉树中某个节点即使只有一个子树也要区分是左子树还是右子树;
    而对于有序树来说,如果某个节点只有一个子树就必定是第一个子树

  7. 二叉树所有结点的形态有5种:空节点,无左右子树节点,只有左子树节点,只有右子树节点和左右子树均存在的节点

  8. 满二叉树:在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有叶子节点都在同一层,则这样的二叉树称作满二叉树
  9. 完全二叉树:如果一颗具有n个节点的二叉树的结构与满二叉树的前n个节点的结构相同,这样的二叉树称为完全二叉树
  10. 二叉树的性质

1)若规定根节点的层数为0,则一棵非空二叉树的第i层上最多有2^i(i>=0)个节点
2)若规定只有根节点的二叉树的深度为0,则深度为k的二叉树的最大节点数是2^(k+1)-1(k>=-1)
3)对于一棵非空的二叉树,如果叶节点个数为n0,度为2的节点个数为n2,则有n0=n2+1
4)具有n个节点的完全二叉树的深度k为大于或等于ln(n+1)-1的最小整数
5)对于具有n个节点的完全二叉树,如果按照从上至下和从左至右的顺序对所有节点序号从0开始顺序编号,则对于序号为i(0<=i< n)的节点有:
如果i>0,则序号为i节点的双亲节点的序号为(i-1)/2(/为整除);如果i=0,则序号为i节点为根节点,无双亲节点 如果2i+1<
n,则序号为i节点的左孩子节点的序号为2i+1;如果2i+1>=n,则序号为i节点无左孩子 如果2i+2<
n,则序号为i节点的右孩子节点的序号为2i+2;如果2i+2>=n,则序号为i节点无右孩子

11.二叉树的存储结构

1.二叉树的顺序存储结构 利用性质5,对于完全二叉树可以利用一维数组存储,如果不是完全二叉树,则可以补空节点,使成为完全二叉树在进行存储,
但是对于非完全二叉树,可能要浪费很多的空间。
2.二叉树的链式存储结构 二叉树的链式存储结构就是用指针建立二叉树中节点之间的关系,二叉树最常用的链式存储结构是二叉链。二叉树的二叉链存储结构是一种常用的
二叉树存储结构。二叉链存存储结构的优点时,结构简单,可以方便的构造任何形状的二叉树,并可以方便的实现二叉树的大多数操作。
二叉链存储结构的缺点是,查找当前节点的双亲节点操作实现比较麻烦
3.二叉树的仿真指针存储结构 利用一维数组和结构体实现,利用数组的下标进行仿真指针进行二叉树的操作

下面为具体代码实现:

package tree;

import java.util.LinkedList;
import java.util.List;
/** * * @author xmhzwy@163.com @date: 2017-3-7 * */  
public class BinTreeTraverse {
    private int arr[]={1,2,3,4,5,6,7};
    private static List<Node> nodeList=null;
    private static class Node{
        Node leftchild;
        Node rightchild;
        int data;
        Node(int newdata){
            leftchild=null;
            rightchild=null;
            data=newdata;
        }

    }
    public void createBintree(){//新建一个二叉树
        nodeList=new LinkedList<Node>();
        for (int nodIndex = 0; nodIndex < arr.length; nodIndex++) {
            nodeList.add(new Node(arr[nodIndex]));
        }
        //以下定义主要依据上面讲解的第五条的特性实现
        for (int parentIndex = 0; parentIndex < arr.length/2-1; parentIndex++) {
            //左孩子
            nodeList.get(parentIndex).leftchild=nodeList.get(parentIndex*2+1);
            //右孩子
            nodeList.get(parentIndex).rightchild=nodeList.get(parentIndex*2+2);
        }
        //最后一个父节点,因为最后一个父节点可能没有右孩子,所以单独拿出来处理
        int lastParentIndex=arr.length/2-1;
        //左孩子
        nodeList.get(lastParentIndex).leftchild=nodeList.get(lastParentIndex*2+1);
        if (arr.length%2==1) {
            nodeList.get(lastParentIndex).rightchild=nodeList.get(lastParentIndex*2+2);
        }
    }
     /** * 先序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */  
    public static void preOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        System.out.print(node.data + " ");  
        preOrderTraverse(node.leftchild);  
        preOrderTraverse(node.rightchild);  
    }  

    /** * 中序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */  
    public static void inOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        inOrderTraverse(node.leftchild);  
        System.out.print(node.data + " ");  
        inOrderTraverse(node.rightchild);  
    }  

    /** * 后序遍历 * * 这三种不同的遍历结构都是一样的,只是先后顺序不一样而已 * * @param node * 遍历的节点 */  
    public static void postOrderTraverse(Node node) {  
        if (node == null)  
            return;  
        postOrderTraverse(node.leftchild);  
        postOrderTraverse(node.rightchild);  
        System.out.print(node.data + " ");  
    }  

    public static void main(String[] args) {  
        BinTreeTraverse binTree = new BinTreeTraverse();  
        binTree.createBintree();  
        // nodeList中第0个索引处的值即为根节点 
        Node root = nodeList.get(0);  

        System.out.println("先序遍历:");  
        preOrderTraverse(root);  
        System.out.println();  

        System.out.println("中序遍历:");  
        inOrderTraverse(root);  
        System.out.println();  

        System.out.println("后序遍历:");  
        postOrderTraverse(root);  
    }  

}

输出的结果为:

先序遍历:
1 2 4 5 3 6 7 
中序遍历:
4 2 5 1 6 3 7 
后序遍历:
4 5 2 6 7 3 1 
    原文作者:猛豪
    原文地址: https://blog.csdn.net/q1406689423/article/details/60772217
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞