目录
正文
树的基本概念
1. 树的定义
树是一种数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
每个节点有零个或多个子节点;
没有父节点的节点称为根节点;
每一个非根节点有且只有一个父节点;
除了根节点外,每个子节点可以分为多个不相交的子树。
树的基本术语
- 结点的度和树的度:某个结点的子树个数为结点的度, 树中所有的结点的度中的最大值叫做树的度
- 分支结点与叶子结点:分支结点就是度不为零的节点可以分为单分支结点(度为1)和 n 分支结点(度为n),叶子结点就是度为0的结点如上图标‘#’的结点都是叶子结点
- 路径和路径长度: 树种存在一个结点序列( k 1 k_1 k1, k 2 k_2 k2, k 3 k_3 k3… k n k_n kn),可以从 k 1 k_1 k1 走到 k n k_n kn就称该结点序列为一条路径。路径长度就是该路径所通过的结点数目减去1即可。
- 孩子结点、双亲结点、兄弟结点: 每个结点的后继节点被称为孩子结点(如B、C就是A的孩子结点), 兄弟结点就是有同一个双亲的结点(B和C有同一个双亲A所以B和C就是一对兄弟结点)所以双亲结点就显而易见了。
- 结点层次和树的高度: 树中结点层次的最大值为树的高度,结点层次根的层次为0,根的直接左右孩子层次为1,以此类推层次逐渐递增。
树的性质
- 性质1: 树的结点数等于所有结点数的度数之和加1(这个1就是根节点的度)
- 性质2: 度为m的树的第i层上最多有 m i − 1 m^{i - 1} mi−1个结点
- 性质3: 高度为h的m次树最多有 m h − 1 m − 1 \frac{m^h - 1}{m - 1} m−1mh−1个结点
- 性质4: 具有n个结点的m次树的最小高度为[ log m ( n ( m − 1 ) + 1 ) \log_m{(n(m - 1)+1)} logm(n(m−1)+1)]
其中有一些比较重要的公式
在m次树中计算结点个数时常用的关系有
1.所有的结点的度之和 = n - 1
2.所有结点的度之和 = n 1 n_1 n1 + 2* n 2 n_2 n2 + 3* n 3 n_3 n3 + … + m* n m n_m nm
3.n = n 1 n_1 n1 + n 2 n_2 n2 + n 3 n_3 n3 + … + n m n_m nm
其中 n 1 n_1 n1代表度为1的结点, 前面的系数为 该类型的结点的个数
以上就是树的一些基本概念和关键字了
二叉树
二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个节点
Attention:
度为2的树中至少存在一个结点的度为2,而二叉树没有这个要求
度为2的树不区分左、右子树,而二叉树是严格区分左、右子树的
- 二叉树的特点:
- 每个结点最多有两颗子树,所以二叉树中不存在度大于2的结点。
- 左子树和右子树是有顺序的,次序不能任意颠倒。
- 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。
- 二叉树的性质:
1)在非空二叉树的第i层上最多有 2 i − 1 2^{i - 1} 2i−1个节点(i ≥ \geq ≥ 1)
2)高度为h的二叉树最多有 2 h − 1 2^{h - 1} 2h−1个节点。(h ≥ \geq ≥ 1)
3) n 0 n_0 n0= n 2 n_2 n2+ 1 1 1 其中: n 0 n_0 n0表示度数为0的节点数, n 2 n_2 n2表示度数为2的节点数。
4)在完全二叉树中,具有n个节点的完全二叉树的深度为[ log 2 n \log_2n log2n]+1,其中[ log 2 n \log_2n log2n]是向下取整。
5)若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点有如下特性:
(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;
(2) 若 2i>n,则该结点无左孩子, 否则,编号为 2i 的结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子结点, 否则,编号为2i+1 的结点为其右孩子结点。
- 斜树:所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。这完全可以脑补出来(就不搞图片了)
- 满二叉树:在一棵二叉树中。如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
- 非空满二叉树的特点:
(1)叶子结点都在最下一层
(2)只有度为0的结点和度为2的结点
- 完全二叉树:对一颗具有n个结点的二叉树按层编号,如果编号为
i
(1 ≤ \leq ≤ i ≤ \leq ≤n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。
- 完全二叉树的特点:
(1)叶子结点只能出现在最下层和次下层。
(2)最下层的叶子结点集中在树的左部。
(3)倒数第二层若存在叶子结点,一定在右部连续位置。
(4)如果结点度为1,则该结点只有左孩子,即没有右子树。
(5)同样结点数目的二叉树,完全二叉树深度最小。
(6)当结点总数n为奇数时, n 1 n_1 n1=0,当结点总数为偶数时 n 1 n_1 n1=1。
- 二叉树的遍历 ------ 采用递归实现
- 先序遍历:
主要方式为 :根结点 -> 左子树 -> 右子树
void Preorder(Bnode *root)
{
if(root)
{
print("%c",root -> val);//根
Preorder(root -> left);//左
Preorder(root -> right);//右
}
}
- 中序遍历:
主要方式为:左子树 -> 根结点 -> 右子树
void Inorder(Bnode *root)
{
if(root)
{
Inorder(root -> left);//左
print("%c",root -> val);//根
Inorder(root -> right);//右
}
}
- 后序遍历:
主要方式为:左子树 -> 左子树 -> 根结点
void Postorder(Bnode *root)
{
if(root)
{
Postorder(root -> left);//左
Postorder(root -> right);//右
print("%c",root -> val);//根
}
}
为了帮助理解特地献上一份 文章 <----
点击跳转
并查集
并查集,在一些有N个元素的集合应用问题中,我们通常是在开始时让每个元素构成一个单元素的集合,然后按一定顺序将属于同一组的元素所在的集合合并,其间要反复查找一个元素在哪个集合中。这一类问题近几年来反复出现在信息学的国际国内赛题中。其特点是看似并不复杂,但数据量极大,若用正常的数据结构来描述的话,往往在空间上过大,计算机无法承受;即使在空间上勉强通过,运行的时间复杂度也极高,根本就不可能在比赛规定的运行时间(1~3秒)内计算出试题需要的结果,只能用并查集来描述。
并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示----来自百度百科
你会惊奇的发现,百度百科中的例题可以使用下面的并查集巧妙的解决
直接上代码hhh
(1)朴素并查集:
int p[N]; //存储每个点的祖宗节点
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ ) p[i] = i;
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
(2)维护size的并查集:
int p[N], size[N];
//p[]存储每个点的祖宗节点, size[]只有祖宗节点的有意义,表示祖宗节点所在集合中的点的数量
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
size[i] = 1;
}
// 合并a和b所在的两个集合:
size[find(b)] += size[find(a)];
p[find(a)] = find(b);
(3)维护到祖宗节点距离的并查集:
int p[N], d[N];
//p[]存储每个点的祖宗节点, d[x]存储x到p[x]的距离
// 返回x的祖宗节点
int find(int x)
{
if (p[x] != x)
{
int u = find(p[x]);
d[x] += d[p[x]];
p[x] = u;
}
return p[x];
}
// 初始化,假定节点编号是1~n
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
d[i] = 0;
}
// 合并a和b所在的两个集合:
p[find(a)] = find(b);
d[find(a)] = distance; // 根据具体问题,初始化find(a)的偏移量
鸣谢 :
本文部分内容来自此
作者:MrHorse1992
链接:https://www.jianshu.com/p/bf73c8d50dc2
来源:简书
并查集代码来自:
作者:yxc
链接:https://www.acwing.com/blog/content/404/
来源:AcWing
感谢你的阅读 :)