数据结构
想去的远方
做一个自由又自律的人,靠势必实现的决心认真地活着!
展开
-
约德尔测试
题目描述兰博和提莫闲聊之后,回归到了他们的正题,约德尔人的未来。说起约德尔人的未来,黑默丁格曾经提出了一个约德尔测试,将约德尔人的历史的每个阶段都用一个字符表达出来。(包括可写字符,不包括空格。)。然后将这个字符串转化为一个01串。转化规则是如果这个字符如果是字母或者数字,这个字符变为1,其它变为0。然后将这个01串和黑默丁格观测星空得到的01串做比较,得到一个相似率。相似率越高,则约德尔的未来越光明。请问:相似率为多少? 输入 每组输入数据为两行,第一...原创 2021-04-02 09:00:08 · 115 阅读 · 0 评论 -
广义表的扩展线性链表存储(第五章)
/* 广义表的扩展线性链表存储表示 */ typedef enum{ATOM,LIST}ElemTag; /* ATOM==0:原子,LIST==1:子表 */ typedef struct GLNode { ElemTag tag; /* 公共部分,用于区分原子结点和表结点 */ union /* 原子结点和表结点的联合部分 */ { AtomType...原创 2020-04-21 23:19:53 · 1839 阅读 · 1 评论 -
广义表的头尾链表存储表示(2)(第五章 P115 算法5.5,5.6,5.8)
下图是根据上方程序定义的广义表(a,(b,c,d))的存储结构。它的长度为2,第1 个元素为原子 a,第2个元素为子表(b,c,d)。完整代码:下面代码中广义表的书写形式串为HString类型,广义表的书写形式串为SString类型的请转看:https://blog.csdn.net/qq_42185999/article/details/105670079...原创 2020-04-21 23:05:12 · 1669 阅读 · 3 评论 -
广义表的头尾链表存储表示(第五章 P115 算法5.5,5.6,5.8)
/* 广义表的头尾链表存储表示 */ typedef enum{ATOM,LIST}ElemTag; /* ATOM==0:原子,LIST==1:子表 */ typedef struct GLNode { ElemTag tag; /* 公共部分,用于区分原子结点和表结点 */ union /* 原子结点和表结点的联合部分 */ { AtomTyp...原创 2020-04-21 22:50:29 · 1801 阅读 · 0 评论 -
关节点和重连通分量(第七章 P178 算法7.10,7.11)
如何确定关节点?算法 7.10、7.11 的思路是这样的:首先在深度优先遍历图时,不仅标注某顶点是否被访问,还标注它的访问顺序。visited[]不再只是 FALSE 和 TRUE,而是 1~顶点数。由于采用深度优先遍历,某结点的祖先被访问的顺序必先于该结点被访问的顺序。以上图为例,由第 1 个结点 A 深度优先遍历的顺序是:A、L、M、J、B、…… 增加 1 个辅助数组 lo...原创 2020-04-21 22:23:08 · 1221 阅读 · 0 评论 -
弗罗伊德(Floyd)算法(第七章 P191 算法7.16)
用 Dijkstra 算法也可以求得有向图 G=(V,E) 中每一对顶点间的最短路径。方法是:每次以一个不同的顶点为源点重复 Dijkstra 算法便可求得每一对顶点间的最短路径,时间复杂度是 O(n3) 。 弗罗伊德(Floyd)提出了另一个算法,其时间复杂度仍是O(n3) , 但算法形式更为简明,步骤更为简单,数据结构仍然是基于图的邻接矩阵。算法思想 设顶...原创 2020-04-21 21:39:07 · 633 阅读 · 0 评论 -
迪杰斯特拉算法(第七章 P188 算法7.15)
对于给定的有向图G=(V,E)及单个源点Vs,求Vs到G的其余各顶点的最短路径。 针对单源点的最短路径问题,Dijkstra 提出了一种按路径长度递增次序产生最短路径的算法,即迪杰斯特拉(Dijkstra)算法。基本思想 从图的给定源点到其它各个顶点之间客观上应存在一条最短路径,在这组最短路径中,按其长度的递增次序,依次求出到不同顶点的最短路径和路径长度。即按长度递增...原创 2020-04-21 17:24:02 · 986 阅读 · 1 评论 -
求AOE中关键路径和关键活动(第七章 P183 算法7.13,7.14)
关键路径AOV网相对应的是AOE(Activity On Edge) ,是边表示活动的有向无环图,如下图所示。图中顶点表示事件(Event),每个事件表示在其前的所有活动已经完成,其后的活动可以开始;弧表示活动,弧上的权值表示相应活动所需的时间或费用。与AOE有关的研究问题◆ 完成整个工程至少需要多少时间?◆ 哪些活动是影响工程进度(费用)的关键? ...原创 2020-04-21 16:30:43 · 3973 阅读 · 0 评论 -
拓扑排序算法(第七章 P182 算法7.12)
拓扑排序定义 拓扑排序(Topological Sort) :由某个集合上的一个偏序得到该集合上的一个全序的操作。◆ 集合上的关系:集合A上的关系是从A到A的关系 。◆ 关系的自反性:若 有(a,a)∈R,称集合A上的关系R是自反的。◆ 关系的对称性:如果对于a,b∈A ,只要有(a,b)∈R就有(b,a)∈R ,称集合A上的关系R是对称的。◆ 关系...原创 2020-04-21 15:23:13 · 1291 阅读 · 2 评论 -
最小生成树--kruskal(克鲁斯卡尔)算法(第七章 P175)
算法思想设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是其最小生成树。初值:U=V,TE={} 。 对G中的边按权值大小从小到大依次选取。⑴ 选取权值最小的边(vi,vj),若边(vi,vj)加入到TE后形成回路,则舍弃该边(边(vi,vj) ;否则,将该边并入到TE中,即TE=TE∪{(vi,vj)} 。⑵ 重复⑴ ,直到TE中包含有n-1条边为止。...原创 2020-04-21 13:53:14 · 403 阅读 · 0 评论 -
最小生成树(prim算法)(第七章 P174 算法7.9)
最小生成树定义:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。通俗易懂的讲就是最小生成树包含原图的所有节点而只用最少的边和最小的权值距离。因为n个节点最少需要n-1个边联通,而距离就需要采取某种策略选择恰当的边。从定义上分析,最小生成树...原创 2020-04-21 13:09:17 · 1059 阅读 · 0 评论 -
无向图的深度优先生成森林(第七章 P170 算法7.7,7.8)
具有 n 个顶点的无向连通图至少有 n-1 条边,如果只有 n-1 条边,则不会形成环,这样的图称为“生成树”。连通图可通过遍历构造生成树,非连通图的每个连通分量可构造一棵生成树,整个非连通图构造为生成森林。下面程序调用算法 7.7、7.8,将无向图构造为生成森林,并以孩子—兄弟二叉链表存储之。typedef int Status; /* Status是函数的类型,其值是函数结果状...原创 2020-04-20 22:25:05 · 1591 阅读 · 2 评论 -
图的遍历(深度、广度优先搜索算法 )(第七章 P167)
对图的搜索就是对图中顶点的遍历。图中各顶点的关系比较复杂、一个顶点可能有多个邻接顶点,也可能是独立顶点(非连通图)。为了不重复地访问所有顶点,需设立一个访问标志数组 visited[],并置其初值为 FALSE(未被访问)。遍历时只访问那些未被访问过的顶点,且在访问后,将其访问标志的值改为 TRUE。当所有顶点访问标志的值都为TRUE,则图已遍历。遍历一般从图的第 1 个顶点开始。确定遍历顶点...原创 2020-04-20 21:58:34 · 408 阅读 · 0 评论 -
无向图的邻接多重表存储实现(第七章 P166)
无向图的邻接多重表存储结构:上图是根据程序定义的无向图的存储结构。程序中基本操作函数 CreateGraph()是在表头插入边结点的。所以,对于给定的图,它的边结点的链表结构也不惟一,与边的输入顺序有关。采用邻接多重表存储结构, 每条边只生成一个结点。而用邻接表存储结构表示无向图,图的每条边生成两个结点。无向图及其邻接多重表存储结构:...原创 2020-04-20 21:48:01 · 913 阅读 · 0 评论 -
有向图的十字链表存储表示(第七章 P164 算法7.3)
下图是根据程序中定义的带权有向图(有向网)的存储结构。和邻接表相比,十字链表不仅有出弧链表,还有入弧链表,而且不增加链表结点的数量。所以,十字链表在既需要用到出弧,也需要用到入弧的情况下是很方便的。由于程序中基本操作函数 CreateDG()总是在入弧和出弧的表头插入弧结点,所以,对于给定的图,它的弧结点的链表结构也不惟一,而是与弧的输入顺序有关。 从存储结构上...原创 2020-04-20 20:16:14 · 987 阅读 · 2 评论 -
图的邻接表存储实现(第七章 P163)
图的邻接表存储结构:下图分别是有向图和无向网的的邻接表存储结构。要注意的是,为了提高效率,程序中的基本操作函数 CreateGraph()产生链表时总是在表头插入结点。 所以,对于给定的图,即使它的顶点输入顺序相同,邻接表的存储结构也不惟一。邻接表的存储结构还与弧或边的输入顺序有关。有向图的邻接表存储结构:...原创 2020-04-20 18:56:33 · 1296 阅读 · 0 评论 -
图的数组(邻接矩阵)存储实现(第七章 P161 算法7.1,7.2,7.4-7.6)
图是比较复杂的数据结构,它由顶点和顶点之间的弧或边组成。任何两个顶点之间都 可能存在弧或边。在计算机存储图时,只要能表示出顶点的个数及每个顶点的特征、每对顶点之间是否存在弧(边)及弧(边)的特征,就能表示出图的所有信息,并作为图的一种存 储结构。图的数组(邻接矩阵)存储结构:有向图的数组(邻接矩阵)存储结构:...原创 2020-04-20 14:41:40 · 811 阅读 · 0 评论 -
求赫夫曼编码。实现算法6.12的程序
最优二叉树(赫夫曼编码)最优二叉树是带权路径长度最短的二叉树。根据结点的个数、权值的不同,最优二叉树的形状也各不相同。下图是 3 棵最优二叉树的例子。它们的共同特点是:带权值的结点都是叶子结点。权值越小的结点,其到根结点的路径越长。最优二叉树的左右子树是可以互换的,因为这不影响树的带权路径长度。当结点的权值差别大到一定程度,最优二叉树就形成了如图(...原创 2020-04-19 23:12:34 · 629 阅读 · 1 评论 -
二叉树的三叉链表存储表示 (第六章 P126)
二叉树的三叉链表存储结构比二叉链表多一个指向双亲结点的指针,因此,求双亲和左右兄弟都很容易。但在构造二叉树时要另给双亲指针赋值,从而增加了复杂度。由于三叉链表和二叉链表在结构上的相似性,它们有些相应的基本操作也很类似。二叉树的三叉链表存储结构:右图为左图的三叉链表存储结构: typedef int Status; /* St...原创 2020-04-19 18:04:49 · 3793 阅读 · 0 评论 -
树的孩子兄弟存储实现(第六章 P136)
孩子兄弟表示法任意一颗树,它的节点的的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们设置两个指针,分别指向该节点的第一个孩子和此节点的右兄弟。树的(孩子—兄弟)二叉链表存储结构:右图为左图的(孩子—兄弟)二叉链表存储: typedef int Status; /* Status是函数的类型,其值是函...原创 2020-04-19 17:46:29 · 1001 阅读 · 0 评论 -
树的双亲表存储实现(第六章 P135)
双亲表示法双亲表示法采用顺序表(也就是数组)存储普通树,其实现的核心思想是:顺序存储各个节点的同时,给各节点附加一个记录其父节点位置的变量。注意,根节点没有父节点(父节点又称为双亲节点),因此根节点记录父节点位置的变量通常置为 -1。树的双亲表存储结构:采用双亲表存储树的示例:typedef int Status; ...原创 2020-04-19 17:35:03 · 297 阅读 · 0 评论 -
二叉树的二叉线索存储(第六章 P132 算法6.5-6.7)
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#include<malloc.h> /* malloc()等 */#include<stdio.h> /* EOF(=^Z或F6)...原创 2020-04-19 17:23:30 · 991 阅读 · 0 评论 -
开放定址哈希表的实现(第九章 P259 算法9.17,9.18)
简介哈希表,也称散列表,是实现字典操作的一种有效的数据结构。尽管最坏情况下,散列表查找一个元素的时间与链表中查找的时间相同,达到了O(n)。然而在实际应用中,散列表查找的性能是极好的。在一些合理的假设下,在散列表中可以查找一个元素的平均时间是O(1)。哈希表的精髓在于哈希二字上面,也就是数学里面常用到的映射关系。它是通过哈希函数将关键字映射到表中的某个位置上进行存放,以实现快速插入和查询的...原创 2020-04-16 11:49:03 · 673 阅读 · 3 评论 -
Trie键树的实现(第九章 P249 算法9.16)
键树又称为数字查找树,它是一棵度 >= 2的树,同以往所学习的树不同的是,键树的结点中存储的不是某个关键字,而是只含有组成关键字的单个符号。如果关键字本身是字符串,则键树中的一个结点只包含有一个字符;如果关键字本身是数字,则键树中的一个结点只包含一个数位。每个关键字都是从键树的根结点到叶子结点中经过的所有结点中存储的组合。例如,当使用键树表示查找表{CAI,CAO,CHEN,...原创 2020-04-16 11:12:08 · 293 阅读 · 0 评论 -
双链键树的实现(第九章 P248 算法9.15)
键树又称为数字查找树,它是一棵度 >= 2的树,同以往所学习的树不同的是,键树的结点中存储的不是某个关键字,而是只含有组成关键字的单个符号。如果关键字本身是字符串,则键树中的一个结点只包含有一个字符;如果关键字本身是数字,则键树中的一个结点只包含一个数位。每个关键字都是从键树的根结点到叶子结点中经过的所有结点中存储的组合。例如,当使用键树表示查找表{CAI,CAO,CHEN,...原创 2020-04-16 10:55:39 · 287 阅读 · 0 评论 -
B-树的实现(第九章 P239 算法9.13,9.14)
文章论述部分转自:https://blog.csdn.net/qq_35644234/article/details/669692381、背景知识二叉查找树查询的时间复杂度是,从算法逻辑上来讲,二叉查找树的查找速度和比较次数都是最小的。但是,我们不得不考虑一个现实问题:磁盘 IO 。数据库索引是存储在磁盘上的,当数据量比较大的时候,索引的大小可能有几个 G 甚至更多。当我们利...原创 2020-04-16 10:39:03 · 573 阅读 · 0 评论 -
平衡二叉树的实现(第九章 P233 算法9.9-9.12)
平衡二叉树前言在计算机科学中,AVL树是最早被发明的自平衡二叉查找树。在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是O(logn)。增加和删除元素的操作则可能需要借由一次或多次树旋转,以实现树的重新平衡。为什么要有平衡二叉树二叉搜索树一定程度上可以提高搜索效率,但是当原序列有序时,...原创 2020-04-15 16:01:18 · 484 阅读 · 0 评论 -
插分查找,斐波那契查找,分块查找(有序表的查找)
三、插分查找在一个0~10000之间的100个元素从小到大均匀分布的数组中查找5,我们自然会考虑从数组下标较小的开始查找,因此二分查找还有提高空间。mid = (low+high)/2 = low+1/2(high-low)。在这公式中我们将这个1/2进行修改:mid = low + (key-a[low])/a[high]-a[low](high-low)。比如在a[...原创 2020-04-13 14:55:15 · 841 阅读 · 0 评论 -
动态查找表(二叉排序树)(第九章 P227 算法9.5-9.8)
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#include<malloc.h> /* malloc()等 */#include<stdio.h> /* EOF(=^Z或F6)...原创 2020-04-13 17:22:19 · 627 阅读 · 0 评论 -
静态树表(次优查找树)(第九章 P222 算法9.3,9.4)
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */#include<malloc.h> /* malloc()等 */#include<stdio.h> /* EOF(=...原创 2020-04-13 16:00:51 · 1063 阅读 · 0 评论 -
顺序查找,折半查找(顺序表的查找)(第九章 P216 算法9.1,9.2)
静态查找表的顺序存储表示与实现typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */typedef int KeyType; /* 设关键字域为整型 */#include<malloc.h>...原创 2020-04-13 11:57:00 · 2222 阅读 · 1 评论 -
归并排序(第十章 P283 算法10.12,10.13,10.14)
概述:排序过程:算法性能:#include<stdio.h> /* EOF(=^Z或F6),NULL */ /* 对两个数值型关键字的比较约定为如下的宏定义 */#define EQ(a,b) ((a)==(b))#define LT(a,b) ((a)<(b))#define LQ(a,b) ((a)&l...原创 2020-04-07 11:33:20 · 438 阅读 · 0 评论 -
链式基数排序(第十章 P286 算法10.15,10.16,10.17)
概述:排序过程:#include<malloc.h> /* malloc()等 */#include<stdio.h> /* EOF(=^Z或F6),NULL */typedef int InfoType; /* 定义其它数据项的类型 */typedef int KeyType; /* 定义RedType类型的关键...原创 2020-04-07 18:11:11 · 2535 阅读 · 1 评论 -
堆排序(第十章 P280 算法10.10,10.11)
堆排序概述:排序过程:算法性能:#include<stdio.h> /* EOF(=^Z或F6),NULL */ /* 对两个数值型关键字的比较约定为如下的宏定义 */#define EQ(a,b) ((a)==(b))#define LT(a,b) ((a)<(b))#define LQ(a,b) (...原创 2020-04-07 10:51:05 · 478 阅读 · 0 评论 -
树形选择排序(第十章 P279)
树形选择排序概述:树形选择排序(又称锦标赛排序),是一种按照锦标赛的思想进行选择排序的方法。首先对n个记录的关键字进行两两比较,然后在n/2个较小者之间再进行两两比较,如此重复,直至选出最小的记录为止。排序过程:树形选择排序(Tree Selection Sort),这个过程可用一棵有n个叶子结点的完全二叉树表示。例如,图中的二叉树表示从8个数中选出最小数的过程。...原创 2020-04-05 14:06:18 · 3170 阅读 · 0 评论 -
简单选择排序(第十章 P277 算法10.9)
简单选择排序概述:简单选择排序算法思想:从要排序的数列中找出最小的数min,然后将其排到数组的最前面,即a[0]的位置(假设数组名为a,长度为n)。然后又在剩余的n-1个中找出最小值,将它排到a[1]的位置,如此经过n-1选择,排序最小值之后,我们就得到了一个有序数列。排序过程:简单选择排序的基本思想:比较+交换。从待排序序列中,找到关键字最小的元素; 如...原创 2020-04-05 12:26:01 · 347 阅读 · 0 评论 -
快速排序(第十章 P274 算法10.6,10.7,10.8)
快速排序目录快速排序概述:排序过程: 一趟快排过程: 排序的全过程:算法性能:代码:概述:快速排序(又称划分交换排序,简称快排),快速排序是对起泡排序的一种改进。快速排序流程: 从数列中挑出一个基准值。 将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基...原创 2020-04-03 21:55:20 · 505 阅读 · 0 评论 -
起泡排序(第十章 P273)
起泡排序概述:冒泡排序(起泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端,故名。排序过程:算法描述: i从0开始,R[i]与 R[i+1] 比较,如果 R[i...原创 2020-04-03 16:53:18 · 308 阅读 · 1 评论 -
希尔排序(第十章 P271 算法10.4,10.5)
希尔排序概述:希尔排序是插入排序的一种,又称“缩小增量排序”。是直接插入排序算法的一种更高效的改进版本。希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。排序过程:如下图,为需要排序的初始关键字。 首先把较大的数据集合分割成若干个小组(逻辑上...原创 2020-04-03 16:32:04 · 576 阅读 · 0 评论 -
表插入排序(第十章 P267 算法10.3,10.18)
表插入排序概述:表插入排序,即使用链表的存储结构对数据进行插入排序。在对记录按照其关键字进行排序的过程中,不需要移动记录的存储位置,只需要更改结点间指针的指向。排序过程:在使用数组结构表示的链表中,设定数组下标为 0 的结点作为链表的表头结点,并令其关键字取最大整数。则表插入排序的具体实现过程是:首先将链表中数组下标为 1 的结点和表头结点构成一个循环链表,然后将后序...原创 2020-04-02 21:55:45 · 310 阅读 · 0 评论