文章目录
二叉树
二叉树简介
二叉树是由 n 个结点组成的有序集合,集合或者为空,或者是由一个根结点加上两颗分别称为左子树和右子树的、互不相交的二叉树组成。
二叉树的五种形态
满二叉树
如果二叉树中所有分支的结点都为2,并且叶子结点在统一层次上,则二叉树称为满二叉树。
完全二叉树
如果一个具有 n 个结点的高度为 k 的二叉树,树的每个结点都与高度为 k 的满二叉树中编号为1到n的结点一一对对应,则二叉树为完全二叉树。
二叉树的特性
- 在二叉树的第 i 层上,最多右 2^(i - 1) 个结点
- 高度为 k 的二叉树,最多有 2^k - 1个结点
- 对任何一颗二叉树,如果其叶结点有 n 个,度为2的非叶结点有 m 个,则 n = m + 1
- 具有 n 个结点的完全二叉树的高度为 logn + 1
二叉树抽象数据类型及存储结构
- 二叉树抽象数据类型
二叉树的抽象数据类型也有插入、删除、查找等操作。同时 ,二叉树还有四种遍历算法。
/*
* 现在我们声明二叉树的抽象数据类型顶级接口 Tree 如下:
* T 表示结点元素的类型,该类型必须实现 Comparable 接口,方便比较数据
* */
package Tree;
import jdk.nashorn.internal.ir.BinaryNode;
public interface Tree<T extends Comparable> {
//判空
boolean isEmpty();
//二叉树结点个数
int size();
//返回二叉树的高度或者深度,即结点的最大层次
int height();
//先根次序遍历
String preOrder();
//中根次序遍历
String inOrder();
//后根次序遍历
String postOrder();
//层次遍历
String levelOrder();
//将 data 插入
void insert(T data);
//删除
void remove(T data);
//查找最大值
T findMax();
//查找最小值
T findMin();
//根据值找到结点
BinaryNode findNode(T data);
//是否包含某个值
boolean contains(T data) throws Exception;
//清空
void clear();
}
- 二叉树的存储结构
二叉树的存储结构主要采用链式存储结构。- 二叉树的二叉链表存储结构
二叉链表结构主要由一个数据域和两个分别指向左、右孩子的结点组成,其结构如下:
BinaryNode(T data, BinaryNode<T> left, BinaryNode<T> right)
从图中可以看出,采用二叉链表存储结构,每个结点只存储了到其孩子结点的单向关系,而没有存储到其父结点的关系,这样的话,每次要获取父结点时要消耗较多的时间,因为要从 root 根结点开始寻找,花费的时间是遍历二叉树的时间,而且与该结点的位置有关。为了更高效地获取父节点,三叉链表存储结构孕育而生。
- 二叉树的二叉链表存储结构
- 二叉树的三叉链表存储结构
三叉链表存储结构主要是在二叉链表的基础上多添加了一个指向父节点的域:
TreeNode(T data, TreeNode<T> parent, TreeNode<T> left, TreeNode<T> right)
二叉树的设计与实现
为了使二叉树的实现更具有具体意义,我们将实现一种叫做二叉查找树的数据结构。二叉查找树的特性是,对于树中的每个结点T(T可能是父结点),它的左子树中所有项的值小T中的值,而它的右子树中所有项的值都大于T中的值。二叉查找树采用二叉链表存储结构实现,其结点 BinaryNode声明如下:
二叉树的遍历算法
二叉树的遍历算法主要由四种:先根次序遍历、中根次序遍历、后根次序遍历和层次遍历
先根次序遍历算法
访问规则是先遍历根结点,再遍历左子树,最后遍历右子树
//先序遍历
@Override
public String preOrder() {
String sb = preOrder(root);
if(sb.length() > 0){
sb = sb.substring(0, sb.length()-1);
}
return sb;
}
private String preOrder(BinaryNode<T> subTree){
StringBuffer sb = new StringBuffer();
if(subTree != null){
//先访问根结点
sb.append(subTree.data + ",");
//遍历左子树
sb.append(preOrder(subTree.left));
//遍历右子树
sb.append(preOrder(subTree.right));
}
return sb.toString();
}
中根次序遍历
访问的规则是先遍历左子树,再遍历根结点,最后遍历右子树
后根次序遍历算法
访问规则是先访问左子树,再访问右子树,最后访问根结点
二叉搜索树
- 定义
二叉搜索树(BST)又称二叉查找树或二叉排序树。 - 基本性质
- 若任意结点的左子树不为空,则左子树上的所有结点的值均不大于它根结点的值;
- 若任意结点的右子树不为空,则右子树上的所有结点的值均不小于它根结点的值;
- 任意结点的左右子树也分别为二叉搜索树。
二叉查找树插入算法的设计与实现(递归)
事实上对于二叉查找树的插入操作的设计是比较简单,我们只要利用二叉查找树的特性(即对每个父结点,它的左子树中所有项的值小T中的值,而它的右子树中所有项的值都大于T中的值),找到只对应的插入位置即可。
插入结点的实现逻辑和递归查找很像:如果树是空的,就返回一个含有该键值对的新结点;如果被查找 的键小于根节点的键,我们会继续在左子树插入该键,否则在右子树中插入该键。