目录
树的概念以及结构
树的概念
树是一种非线性的数据结构,是由n个有限节点组成一个具有层次关系的集合。例如祖先-后代,上级-下属,整体-部分以及其他类似的关系。把他叫做树,是因为它看起来像一颗倒挂的树,也就是说它的根朝上,而叶子朝下。
- 每个树有个特殊的结点,即是根结点,此节点没有前驱结点。
- 除了根结点外,其它结点被分成了M个互不相交的集合X1,X2,X3...Xm,其中每一个集合Xi(1<=i<=m)又是一颗结构与树类似的子树。而每颗子树都仅且只有一个前驱,可以有0或多个后继。
- 树是递归定义的。
树的相关概念(与人类的亲缘关系相似):
- 树的另一常用”级“表示。例如:树根是1级,以树根为前驱的子树为2级,依次类推。
- 一个元素的度指其孩子(其子树)的个数。
- 一个树是由高度或者深度的,而高度或者深度是指树中级的个数。
- 一个元素的度是指一个结点含有子树的个数。
- 度为0的结点为叶的非终端结点或分支结点。
- 如果一个结点含有子节,则这个节点称为其子结点的父结点。
- 一个结点含有的子树的根结点称为该结点的子结点。
- 具有相同的父结点的结点互称为兄弟结点。
- 一棵树的度指其元素的度的最大值。
- 从根到该结点所经分支上的所有节点称为结点的祖先。
- 以某一结点为根的子树为任一结点都称为该结点的子孙。
- 由N(N>0)棵互不相交的树的结合称为森林。
- 子树是不相交的;
- 除了根结点外,每个结点有且仅有一个父结点;
- 一棵N个结点的树有N-1条边。
树的定义
struct TreeNode
{
int val;
struct TreeNode* child1;
struct TreeNode* child2;
struct TreeNode* child3;
//...
}
#define N 3
struct TreeNode
{
int val;
struct TreeNode* childArr[N];
}
有缺陷:空间可能会浪费,例如树的度为6,而其他结点的子树只有1到2个,导致空间浪费。
最好方法用顺序表存储子树的指针:左孩子右兄弟表示法
上图是一个简单的树,用左孩子右兄弟表示法可以写成下图形式。
左孩子右兄弟表示法
先用指针指向最左边的孩子,剩下的孩子用兄弟指针链接起来。
代码表示如下
TreeNode* Anode;
TreeNode* child = Anode-> firstchild;
while(child)
{
printf("%d",child->val);
child = child->nextbrother;
}
双亲表示法(数组表示法)
只存储双亲的下标或指针
一:
二:
若根相同,则两个结点在同一棵树上。
二叉树的概念以及结构
- 二叉树是树的一种特殊形式。
- 二叉树不存在大于2的结点,最多有两个孩子;
- 二叉树的子树有左右之分,次序不能颠倒,因此二叉树是一个有序树。
特殊二叉树
1,满二叉树
如果每一个层的结点都达到最大值,那么这个二叉树就是满二叉树。
一个二叉树的层数为K,且结点总数为,则该二叉树为满二叉树。
- 二叉树每层的结点为
- 每一层都是满的
例如:高度为h的满二叉树有多少结点:
2,完全二叉树
完全二叉树说效率很高的数据结构,由满二叉树引出。对于深度为K的,有n个结点的二叉树,当且仅当其中每个结点都与深度为K的满二叉树中编号从1至n的结点一一对应时称之为完全二叉树。(满二叉树是一种特殊的完全二叉树)
二者区别:
假设一个树的高度为h,满二叉树的每一层都是满的,而完全二叉树的前h-1层是满的,但最后一层不一定满,从左到右是连续。
高度为h的满二叉树有结点数为:
而高度为h的完全二叉树的结点数取值范围为:[,
]
二叉树的性质
- 若规定根结点的层数为1,则一棵非空二叉树的第i层上最多有
个结点。
- 若规定根结点的层数为1,则深度为h的二叉树的最大结点数是
。
- 若规定根结点的层数为1,具有n个结点的满二叉树的深度
。
- 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从0开始编号,则对于序号为i的结点有:
- 若i>0,i位置结点的双亲序号:
; i = 0,i为根结点编号,无双亲结点。
- 若2i+1<n,左孩子序号:
,
否则无左孩子。
- 若2i+2<n,右孩子序号:
,
否则无右孩子。
- 若i>0,i位置结点的双亲序号: