目录
树形结构
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。它是根朝上,而叶朝下的。
树形结构特点
- 有一个特殊的节点,称为根节点,根节点没有前驱节点
- 除根节点外,其余节点被分成M(M > 0)个互不相交的集合T1、T2、......、Tm,其中每一个集合 Ti (1 <= i <= m) 又是一棵与树类似的子树。每棵子树的根节点有且只有一个前驱,可以有0个或多个后继
- 树是递归定义的。
树
- 子树之间不能相交
- 除了根节点之外,每个节点有且只有一个父节点
- 一颗N个节点的树有N-1条边
一些概念
树中每个单元称为节点,AB都是节点
1.节点的度:该节点含有的子树个数称为节点的度,A节点的度是6,G节点的度是1
2.树的度:这个树中最大的节点的度就是该树的度,上图树的度是6
3.叶子节点:度为0的节点称为叶子节点,BC都是叶子节点
4.对于A和B两个节点来说,双亲节点/父节点A,孩子节点/子节点B
5.根节点:树中没有父亲节点的节点称为根节点,上图A就是根节点
6.节点的层次:从根节点开始计算,根节点是第一层,A的层次是1,H是3
7.树的高度:节点的最大层次,上图树的高度是4
二叉树
- 每个结点最多有两棵子树,即二叉树不存在度大于 2 的结点
- 二叉树的子树有左右之分,其子树的次序不能颠倒,因此二叉树是有序树
两种特殊的二叉树
满二叉树
一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果 一个二叉树的层数为K,且结点总数是2^k - 1 ,则它就是满二叉树如下图
完全二叉树
完全二叉树是由满二叉树而引出来的,对于深度为K的,有n 个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。完全二叉树的节点编号和满二叉树一一对应。 满二叉树是一种特殊的完全二叉树。
注意
- 一个二叉树高度为k,则该二叉树最多有2^k -1个节点(满二叉树)
- 一个二叉树层次为k,第k层最多有2^(k-1)个节点
- 具有n个结点的完全二叉树的深度k= log2(n+1)上取整
- 边长=节点个数-1
- 设度为0的节点个数为n0,度为1的节点个数为n1,度为2的节点个数为n2,n0=n2+1
- 如果根节点从1开始编号,设父节点的编号为k,则左子树为2k,右子树为2k+1,如果根节点从0开始编号,则左子树为2k+1,右子树为2k+2,如果子节点编号是k,那么父节点编号是k/2
例题:假设一棵完全二叉树中总共有1000个节点,则该二叉树中_____个叶子节点,_____个非叶子节点,_____ 个节点只有左孩子,_____个只有右孩子
答案:500,500,1,0
解析:这个二叉树总共有1000个节点,那么这个二叉树的深度k=log2(1000+1)取整=10
说明这个二叉树总共有10层,那么当这个二叉树为满二叉树的时候总共有2^10 -1=1023个
说明这个二叉树第十层是不满的,1-9层的节点总数=2^9 -1=511个节点,
第10层的节点个数= 1000-511=489,这489个都是叶子节点,
489/2=244.......1取整得到245,这245个节点都有子节点
第9层总共有2^8=256个节点,256-245=11个节点,这11个节点都是叶子节点
所以:
共有489+11=500个叶子节点,
非叶子节点=1000-500=500个节点,
第9层有一个节点只有左孩子,
没有只有右孩子的节点
二叉树的存储
二叉树的存储结构分为:顺序存储(采用数组方式)和类似于链表的链式存储
普通的二叉树采用引用方式来存储
class Node<E> {
E val; // 数据域
Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
}
class Node<E> {
E val; // 数据域
Node left; // 左孩子的引用,常常代表左孩子为根的整棵左子树
Node right; // 右孩子的引用,常常代表右孩子为根的整棵右子树
Node parent; // 当前节点的根节点
}
二叉树的遍历
遍历
按照一定的顺序访问访问结点所做的操作 依赖于具体的应用问题(比如:打印节点内容、节点内容加1)
深度优先遍历
前序遍历
NLR:前序遍历/先序遍历(Preorder Traversal )——访问根结点--->根的左子树--->根的右子树
中序遍历
LNR:中序遍历(Inorder Traversal)——根的左子树--->根节点--->根的右子树
后序遍历
LRN:后序遍历(Postorder Traversal)——根的左子树--->根的右子树--->根节点
广度优先遍历
层序遍历(levelOrder):按照二叉树的层次一层层访问,先左再右边(A->B->C->D->E)
例题: