第二次测验大复习
数据结构——树和图
先把数据结构搞清楚,程序的其余部分自现。
—— David Jones
树与二叉树
所谓树,存储的是具有“一对多”关系的数据元素的集合。自然界的树可能有很多分支,而数据结构研究的树主要为二叉树。
二叉树,是一种特殊的树,其每个结点至多只有两棵子树。也就是说,二叉树中不存在度大于2的结点。
二叉树有以下几个很好的性质:
利用上述性质,可以解决二叉树的结点计算问题,例如:
若一棵二叉树具有10个度为2的结点,5个度为1的结点,则度为0的结点个数为_____.
解:根据上述性质(3),可知度为0的结点个数为度为2的结点个数加1,也就是10+1=11,因此本题答案为11.
二叉树有下面五种基本形态:
(a) 空二叉树;
(b) 仅有根节点的二叉树;
(c) 右子树为空的二叉树;
(d) 左子树为空的二叉树;
(e) 包含左、右子树的二叉树。
二叉树的前序遍历、中序遍历和后序遍历具有统一性,其代码可统一描述如下:
已知中序遍历与其他任意一种遍历序列都可以求出整个树,如果没有中序遍历序列则不能求出整个树。
层序遍历是按层的顺序进行遍历,先遍历第1层的结点,再遍历第2层的结点……直到遍历完所有结点。
层序遍历的实现需要一个队列,每遍历一个结点就把这个结点的左右子树加入队列。如果队列非空,就从队列中提取元素遍历。代码如下:
哈夫曼编码
哈弗曼编码(Huffman Coding),主要目的是根据出现频率来最大化节省字符(编码)的存储空间。
哈夫曼树,又称最优二叉树,是带权路径长度(WPL)最短的树,权值较大的结点离根较近。
建立哈夫曼树算法步骤:
(1) 从序列中依次找到两个最小元素a和b作为左孩子和右孩子建立二叉树结点c;
(2) 从原序列中删除a和b,并在原序列尾插入c;
(3) 重复(1)(2)直到序列中只剩下一棵树,即为哈夫曼树。
前缀编码:设计长短不等的编码,必须是任一字符的编码都不是另一个字符编码的前缀,这种编码称为前缀编码。
图
图是具有"多对多"逻辑关系数据的结构。
图也有很多性质,如:
(1) 具有n个顶点的无向图最多有n(n-1)/2条边;
(2) 具有n个顶点的有向图最多有n(n-1)条弧;
(3) 具有n个顶点的无向图中,要连通全部顶点至少需要n-1条边;
(4) 一个有n个顶点的无向图,最少有1个连通分量;
(5) 一个有n个顶点的无向图,最多有n个连通分量;
(6) 一个有向图中,共有n条弧,则所有顶点的度的总和为2n;
(7) 具有n个顶点的无向图,当有(n-1)(n-2)/2+1条边时能确保是一个连通图;
(8) 若有向图中有k条边,则相应的邻接表中就有k个边结点。
图的最小生成树
普里姆算法步骤:
(1) 把起点加入集合U;
(2) 找集合U中的元素到集合V-U中的元素的代价最小边(借助closedge数组)到达的结点,加入集合U;
(3) 重复(2)执行n-1轮,得到最小生成树。
代码如下:
克鲁斯卡尔算法即每次找到一个最短边并建立,循环n-1次后即可完成最小生成树,代码略。
拓扑排序
拓扑排序算法步骤:
(1) 选择一个入度为0的顶点并输出之;
(2) 从图中删除此顶点及出边;
(3) 重复(1)(2),直到不存在入度为0的顶点,此时判断已输出顶点数是否与原有顶点相等,如果不等则出现回路。
代码如下:
最短路径
Dijkstra算法算是贪心思想实现的,首先把起点到所有点的距离存下来找个最短的,然后松弛一次再找出最短的,所谓的松弛操作就是,遍历一遍看通过刚刚找到的距离最短的点作为中转站会不会更近,如果更近了就更新距离,这样把所有的点找遍之后就存下了起点到其他所有点的最短距离。
Floyd算法的核心思想是动态规划,其步骤可大致描述为:
(1) 从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
(2) 对于每一对顶点u和v,看看是否存在一个顶点w使得从u到w再到v比已知的路径更短。如果是更新它。
代码短小精干,只有短短五行,如下:
无向图的基本操作
有向图的基本操作
-the end-
祝大家考出好成绩!
关注精英计划团
获得更多讲座信息、学习技巧、竞赛资料等
文案 | 冯明喆
排版 | 冯明喆