Java数据结构之二叉树
基本概念
- 普通二叉树:二叉树是特殊的有序树,当n=0时为空二叉树。二叉树的每个结点最多只有两颗子树,子树也为二叉树,互不相交且有左右之分,分别称为左二叉树和右二叉树。
- 满二叉树:一种特殊的二叉树,要求除叶结点外的其他结点都具有两个子树,并且所有的叶结点在同一层,如图1。
- 完全二叉树:一种特殊的二叉树,若完全二叉树具有n个结点,它要求n个结点与满二叉树的前n个结点具有完全相同的逻辑结构,如图2。
性质
- 二叉树中第i层的结点数最多为2i
- 深度为h的二叉树最多有2h-1个结点
- 若二叉树的叶结点的个数为n,度为2的结点个数为m,有n=m+1
- 具有n个结点的完全二叉树,其深度为log2(n+1)
- 具有n个结点的完全二叉树,从根结点开始自上而下、从左向右对结点从0开始编号。对任意一个编号为i的结点:
- 若i=0,结点为根结点,没有父节点;若i>0,则父节点的编号为(i-1)/2
- 若2i+1>=n,该结点无左孩子,否则左孩子结点的编号为2i+1
- 若2i+2>=n,该结点无右孩子,否则右孩子结点的编号为2i+2
存储结构
顺序存储结构
顺序存储结构是指将二叉树的各个结点存放在一组地址连续的存储单元中,所有结点按照结点序号进行顺序存储。由于二叉树为非线性结构,所以必须先将二叉树的结点排成线性序列再进行存储。二叉树的各结点间的逻辑关系由结点在线性序列中的相对位置确定。
可利用性质5将二叉树的结点排成线性序列,将节点存放在下标为对应编号的数组元素中。为了存储非完全二叉树,需要在树中添加虚结点使其成为完全二叉树后再进行存储,这样会造成空间浪费,如图3。
链式存储结构
链式存储结构指将二叉树的各个结点随机存放在存储空间中,二叉树的各结点间的逻辑关系由指针确定。
二叉链式存储结构
由两个指针域和一个数据域组成,指针域分别存放左、右孩子结点的存储地址,如图4。
该存储结构没有保存该结点与其父结点的关系,因此要获取其父结点花费时间较多。
二叉链式存储结构的结点类
package ch05;
/*二叉链式存储结构节点类*/
public class BiTreeNode {
public Object data; // 数据域
public BiTreeNode lchild, rchild; // 指针域;lchild:左孩子;rchild:右孩子
public BiTreeNode() {
this(null,null,null);
}
public BiTreeNode(Object data) {
this(data,null,null);
}
public BiTreeNode(Object data, BiTreeNode lchild, BiTreeNode rchild) {
this.data = data;
this.lchild = lchild;
this.rchild = rchild;
}
}
二叉链式存储结构的树类
public class BiTree {
public BiTreeNode root; // 根结点
public BiTree() {
this(null);
}
public BiTree(BiTreeNode root) {
this.root = root;
}
}
三叉链式存储结构
由三个指针域和一个数据域组成,指针域分别存放左、右孩子结点和父结点的存储地址如图5。