1.树的概念以及结构
1.1树的概念
- 树是一种非线性的结构它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
- 有一个特殊的节点,称为根节点,根节点没有前驱节点。
- 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i<= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继因此,树是递归定义的
- 树形结构中,子树之间不能有交集,否则就不是树形结构。
1.2 树与非树
- 子树是不相交的。
- 除了根节点意外,每个节点有且仅有一个父节点。
- 一个n个节点的树有n - 1条边。
- n个节点:1个根节点(没有双亲,根往上什么都没有) + n - 1 个非根节点(每个非根节点都是有双亲的每个非根结点跟双亲只有一条边)
1.3相关术语
- 节点的度:一个节点含有子树的个数称为该节点的度 ,如上图A的度是6,F的度是3。
- 叶子节点或终端结点:度为0的节点,如上图B,C,H,I,P,Q,K,L,M,N。
- 非终端节点或分支节点:度不为0的节点,如上图D,E,J,F,G。
- 双亲节点或者父节点:若一个节点含有双亲向上有边,这个双亲则是本节点的父节点,或者双亲节点。
- 孩子节点或者子节点:一个节点含有的子树的根节点称为该节点的子节点; 如上图:B是A的孩子节点
- 兄弟节点:具有相同双亲节点的互称为兄弟节点。
- 树的度:一棵树中最大节点的度称为树的度,如上这个树的度就是6.
- 节点的层次;从跟开始定义起,根为第一层,根的子节点为第二层,以此类推。
- 树的高度或深度:树中节点的最大层次,如上树的高度就是4.
- 堂兄弟节点:双亲同在一层互为堂兄弟:J K就是互为堂兄弟节点。
- 节点的祖先从根节点到该节点所经过的所有节点。
- 子孙:以某节点为根的子树的任一节点都称为该节点的子孙。
- 由m(m > 0)棵互不相交的树称为森林。
1.4树的性质
- 树的节点个数等于所有节点的度数之和 + 1,N个节点的树就有N - 1条边。
- 度为a的树(最大度数)第i层最多有a^i - 1个节点。
- 高度为h的a叉树至多有(a^h - 1)/ (a - 1),满a叉树,等比数列前n项和。
1.5树的表示方法
树结构相对顺序表和链表就复杂了一些。
树的表示:组织数据 + 表示数据和数据之间的关系
树的表示方法:
- 孩子表示法
- 双亲表示法
- 孩子双亲表示法
- 孩子兄弟表示法
1.5.1孩子表示法
每个节点除了保存数据以外还必须指出该节点与其孩子节点的关系
优势:找某个节点的孩子十分的方便
缺陷:找双亲很麻烦
1.5.2双亲表示法
每个节点除了保存数据外,还必须表现出该节点与其双亲之间的关系。
优点:找某个节点的双亲非常方便
缺陷:找孩子十分麻烦
1.5.3孩子双亲表示法
也就是孩子表示法加上双亲表示法 两个指针了
1.5.4孩子兄弟表示法
节点中有数据域和一个指向该节点的第一个孩子和指针指向该节点的下一个兄弟。
2.二叉树的概念以及结构
2.1二叉树的概念
- 空树
- 非空树:跟节点 + 根节点的左子树 + 跟节点的右子树
特点:
- 二叉树不存在度大于2的节点。
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树。
2.2二叉树的基本结构
2.3特殊的二叉树
- 满二叉树:一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为K,且结点总数是 ,则它就是满二叉树。
- 完全二叉树:完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。
- 若完全二叉树有一个节点度为一那他只有左孩子没有右孩子。
- 满二叉树是一种特殊的完全二叉树,但是完全二叉树不是满二叉树。
- 假设完全二叉树有n个节点,若n为奇数则该完全二叉树每一个分支节点上都有左孩子和右孩子,若n是偶数这该完全二叉树则编号最大的分支节点 n / 2 那个节点只有左孩子没有右孩子。
2.4二叉树的性质
1. 若规定根节点的层数为1,则一棵非空二叉树的第i层上最多有 2 ^ ( i - 1 )个结点
证明:
首项为1公比为2(树的叉数 因为是二叉树所以是2)等比数列第i项 就是他。
2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2 ^ i - 1
证明:
首项为1公比为2等比数列前i项和 就是他。
4. 若规定根节点的层数为1,具有n个结点的满二叉树的深度,h= log以2为底i + 1的对数(向上取整;
证明:
假设有n个节点的h层二叉树则满足
n <= 2 ^ h - 1
log以2为底i + 1的对数 <= h h要为整数向上取整
5. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对
于序号为i的结点有:
- 若i>0,i位置节点的双亲序号:(i-1)/2;i=0,i为根节点编号,无双亲节点
- 若2i+1<n,左孩子序号:2i+1,2i+1>=n否则无左孩子
- 若2i+2<n,右孩子序号:2i+2,2i+2>=n否则无右孩子
6.对任何一棵二叉树, 如果度为0其叶结点个数为 n0, 度为 2 的分支结点个数为n2 ,则有 n0 = n2 +1
证明:
假设二叉树有N个节点度为0的节点个数为n0 度为1的节点个数为n1 度为2的节点个数为 n2
则N = n0 + n1 + n2,因为二叉树有N个节点,则他有N - 1条变 度为0的没有边度为1一条边 度为2两条边则有 N - 1 = n1 + 2n2 两个式整合则有 n0 = n2 +1
2.4二叉树的存储
二叉树一般可以使用两种结构存储,一种顺序结构,一种链式结构。
1. 顺序存储顺序结构存储就是使用数组来存储,一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储,二叉树顺序存储在物理上是一个数组,在逻辑上是一颗二叉树。
顺序结构只适合完全二叉树
2. 链式存储
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分为二叉链和三叉链
typedef int Datatype;
// 二叉链
struct BinaryTreeNode
{
struct BinTreeNode* Left; // 指向当前节点左孩子
struct BinTreeNode* Right; // 指向当前节点右孩子
DataType data;
};
// 三叉链
struct BinaryTreeNode
{
struct BinTreeNode* Parent; // 指向当前节点的双亲
struct BinTreeNode* Left; // 指向当前节点左孩子
struct BinTreeNode* Right; // 指向当前节点右孩子
DataType data;
};