二叉树的定义和Java实现

数据结构中有关树的一些定义
  1. 节点:节点包括一个数据元素及若干指向其子树的分支

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

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

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

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

二叉树

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

  1. 二叉树所有结点的5种形态:空节点,无左右子树节点,只有左子树节点,只有右子树节点和左右子树均存在的节点
  2. 满二叉树:在一棵二叉树中,如果所有分支节点都存在左子树和右子树,并且所有叶子节点都在同一层,则这样的二叉树称作满二叉树
  3. 完全二叉树:如果一颗具有n个节点的二叉树的结构与满二叉树的前n个节点的结构相同,这样的二叉树称为完全二叉树
  4. 二叉树的性质
  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节点无右孩子
  1. 二叉树的存储结构
  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 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值