![](https://img-blog.csdnimg.cn/20201021225154885.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构与算法分析
数据结构与算法分析
Revendell
分布式数据库内核开发
展开
-
排序——希尔排序
希尔排序是将待排序的数组元素 按下标的一定增量分组 ,分成多个子序列,然后对各个子序列进行直接插入排序算法排序;然后依次缩减增量再进行排序,直到增量为1时,进行最后一次直接插入排序,排序结束。#include<iostream>using namespace std;#define MaxSize 10#define TRUE 1#define FALSE 0typed...原创 2020-03-17 23:15:18 · 141 阅读 · 0 评论 -
排序——堆排序
堆是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆,用于从小到大排序,堆顶元素依次有序排到队尾,每排一次重新构建一次大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆,用于从大到小排序,堆顶元素依次有序排到队尾,每排一次重新构建一次小顶堆。堆排序(Heap Sort)就是利用堆进行排序的方法。它的基本思想是,将待排序的序列构造成一个大顶堆。此时...原创 2020-03-16 23:28:27 · 164 阅读 · 0 评论 -
排序——快速排序
快速排序(Quick Sort)的基本思想是:通过一趟排序将待排疾苦分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序的目的。#include<iostream>using namespace std;#define MaxSize 10#define TRUE 1#define FALSE 0t...原创 2020-03-14 19:26:48 · 134 阅读 · 0 评论 -
排序——归并排序
归并排序(Merging Sort)就是利用归并的思想实现的排序算法。它的原理是假设初始序列有n个记录,则可以看成是n个有序的子序列,每个子序列的长度为1,然后两两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,...如此重复,直到得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。#include<iostream>using namespace std...原创 2020-03-14 16:11:38 · 171 阅读 · 0 评论 -
排序——直接插入排序
直接插入排序(Straight Insertion Sort)的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增加1的有序表。#include<iostream>using namespace std;#define MaxSize 10#define TRUE 1#define FALSE 0typedef struct{ int r[M...原创 2020-03-10 21:56:08 · 288 阅读 · 0 评论 -
排序——简单选择排序
简单选择排序法(Simple Selection Sort)就是通过n-i次关键字比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1<=i<=n)个记录交换之。#include<iostream>using namespace std;#define MaxSize 10#define TRUE 1#define FALSE 0typedef st...原创 2020-03-10 21:24:22 · 214 阅读 · 0 评论 -
排序——冒泡排序
冒泡排序(Bubble Sort)是一种交换排序,它的基本思路是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。#include<iostream>using namespace std;#define MaxSize 10#define TRUE 1#define FALSE 0typedef struct { int r[MaxSize];...原创 2020-03-10 21:11:59 · 128 阅读 · 0 评论 -
查找——散列表查找(哈希表)
1、散列表查找定义散列技术是在记录的存储位置和它的关键字之间建立一个确定的对应关系f,使得每个关键字key对应一个存储位置f(key)。查找时,根据这个确定的对应关系找到给定值key的映射f(key),若查找集合中存在这个记录,则必定在f(key)的位置上。采用散列技术将记录存储在一块连续的存储空间中,这块连续的存储空间称为散列表或哈希表(Hash Table)。散列技术既是一种存储方法,也是...原创 2020-02-29 19:52:14 · 424 阅读 · 0 评论 -
查找——多路查找树(B树)
多路查找树(multi-way search tree),其每一个节点的孩子数可以多于两个,且每一个节点处可以存储多个元素,所有元素之间存在某种特定的排序关系。主要有四种特殊形式:2-3树、2-3-4树、B树、B+树。1、2-3树...原创 2020-02-24 00:51:51 · 327 阅读 · 0 评论 -
查找——平衡二叉树AVL
1、平衡二叉树是一种二叉排序树,其中每一个结点的左子树和右子树的高度差至多等于1。我们将二叉树上结点的左子树深度减去右子树深度的值称之为平衡因子BF(Balance Factor),距离插入结点最近的,且平衡因子的绝对值大于1的结点为根的子树,我们称之为最小不平衡树。2、平衡二叉树的实现原理:平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的...原创 2020-02-22 14:33:12 · 359 阅读 · 0 评论 -
查找——二叉排序树
二叉排序树(Binary Sort Tree),又称为二叉查找树,它具备以下性质,若它的左子树不为空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不为空,则右子树上所有结点的值均大于它的根结点的值;它的左右子树也分别为二叉排序树。1、二叉排序树的查找操作递归查找二叉排序树T中是否存在key,指针f指向T的双亲,其初始调用值为NULL,若查找成功,则指针p指向该数据元素结点,并返...原创 2020-02-17 16:50:56 · 674 阅读 · 0 评论 -
查找——线性索引查找
数据结构的最终目的是提高数据的处理速度,索引是为了加快查找速度而设计的一种数据结构,索引就是把一个关键字与它对应的记录相关联的过程,一个索引表由若干个索引项构成,每个索引项至少包含关键字和其对应的记录在存储器中的位置等信息。索引技术是组织大型数据库以及磁盘文件的一种重要技术。索引按结构分可以分为线性索引、树形索引和多级索引。这里只介绍线性索引,线性索引就是将索引项集合组织为线性结构,也为索引表...原创 2019-11-26 22:40:52 · 328 阅读 · 0 评论 -
查找——有序表查找
1、折半查找折半查找又称二分查找,时间复杂度为,它的前提t条件是有序顺序存储,对于静态查找表,一次排序后不再变化,这样的算法已经比较好了。但对于需要频繁插入或删除操作的数据来说,维护有序的排序会带来不小的工作量,不建议使用。2、插值查找插值查找是另一种有序表查找算法,其核心就在于插值公式,时间复杂度也是,但对于表长较大且关键字分布均匀的查找表来说,插值查找平均性能比折半查找要好得多。...原创 2019-11-24 14:42:43 · 680 阅读 · 0 评论 -
图——关键路径
AOE网(Activity On Edge Network,边表示活动网)是指在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动持续的时间,这种有向图称为AOE网。通常一个工程总有一个开始一个结束,所以AOE网只有一个源点一个汇点。AOE网和AOV网的区别:AOV网是顶点表示活动的网,它只描述活动之间的制约关系;AOE网是用边表示活动的网,边上的权值表示活动持...原创 2019-11-23 14:42:48 · 471 阅读 · 0 评论 -
图——拓扑排序
拓扑排序就是对一个有向图构造拓扑序列的过程。它解决的是一个工程能否顺序进行的问题。AOV网(Activity On Vertex Nextwork,顶点表示活动的网)是指在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图称为AOV网。拓扑序列是指在一个有n个顶点的有向图中,V中的顶点序列满足从顶点Vi到Vj有一条路径,则在顶点序列中顶点Vi必在顶点Vj之前,...原创 2019-11-22 21:56:13 · 154 阅读 · 0 评论 -
图——最短路径Floyd算法
Floyd算法是解决求图中所有顶点到所有顶点的最短路径,时间复杂度是。Dijkstra算法是求从某个源点到其余各顶点的最短路径问题,时间复杂度是,如果求图中所有顶点到所有顶点的最短路径,需要再运行n次Dijkstra函数,时间复杂度也是。Floyd算法与Dijkstra算法的比较:1、Dijkstra算法更强调单源点查找路径的方式,比较符合正常思路,容易理解原理,但算法代码相对复杂。2...原创 2019-11-18 22:44:24 · 370 阅读 · 0 评论 -
图——最短路径Dijkstra算法
Dijkatra算法解决了从某个源点到其余各顶点的最短路径问题。时间复杂度为。如果我们还需要知道v3到v5、v1到v7这样任一顶点到其余其他顶点的最短距离,可以对每个顶点当作源点运行一次Dijkstra算法,等于在原有算法的基础上,再来一次循环,此时整个算法的时间复杂度就成了。Floyd算法就是求所有顶点到所有顶点的算法,算法非常简洁优雅,能让人感觉到智慧的无穷魅力,其时间复杂度就是。Dijk...原创 2019-11-13 15:16:17 · 559 阅读 · 0 评论 -
图——最小生成树Kruskal算法
Kruskal算法的原理和本质:Kruskal算法直接以边为目标去构建,因为权值是在边上,直接去找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环路而已。Kruskal算法是基于贪心的思想得到的。首先把所有的边按照权值先从小到大排列,接着按照顺序选取每条边,如果这条边的两个端点不属于同一集合,那么就用并查集算法将它们合并,直到所有的点都属于同一个集合为止。换言之,Krusk...原创 2019-11-11 20:51:11 · 303 阅读 · 0 评论 -
图——最小生成树Prim算法
最小生成树问题:对于有n个顶点的带权值的图,用n-1条边把一个连通图连接起来,并且使得连接起来的n-1条边的权值和最小。Prim算法是以某顶点为起点,逐步找未加入生成树的所有顶点中距离生成树最小权值距离的顶点来构建最小生成树。#include<iostream>using namespace std;#define MaxVex 100 //定义最大顶点数#defin...原创 2019-11-09 15:50:14 · 220 阅读 · 0 评论 -
图——广度优先遍历
对比图的深度优先遍历与广度优先遍历算法,它们在时间复杂度上是一样的,不同之处在于对顶点访问顺序不同。可见二者在全图遍历上是没有优劣之分的,只是视不同的情况选择不同的算法。深度优先更适合目标比较明确,以找到目标为主要目的的情况,而广度优先更适合在不断扩大遍历范围时找到相对最优的情况。对于深度优先遍历和广度优先遍历而言,已经不是简单的算法实现问题,完全上升到方法论的角度。#include<...原创 2019-11-06 22:20:02 · 239 阅读 · 0 评论 -
图——深度优先遍历
深度优先遍历其实就是一个递归的过程,它从某个顶点v出发,访问此顶点,然后从v的未被访问的邻接点出发深度优先遍历图,直到图中所有和v有路径想通的顶点都被访问到。对比邻接矩阵和邻接表这两个不同存储结构的深度优先遍历算法,对于n个顶点e条边的图来说,邻接矩阵由于是一个二维数组,要查找每个顶点的邻接点需要访问矩阵中的所有元素,因此需要的时间。而邻接表做存储结构时,找到邻接点所需时间取决于顶点和边的数量...原创 2019-11-06 20:53:21 · 451 阅读 · 0 评论 -
图——图的存储结构(邻接矩阵和邻接表法)
图的五种存储结构:1、图的邻接矩阵表示法图是由顶点和边或弧两部分组成。图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组表示图,一个一维数组存储图中的顶点信息,一个二维数组(邻接矩阵)存储图中边或弧的信息。2、图的邻接表表示法邻接矩阵是一种不错的图存储结构,但我们发现对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此采用邻接表(Adjacency...原创 2019-11-03 15:32:06 · 4064 阅读 · 0 评论 -
树——线索二叉树
1、线索二叉树提出的原因:①终端结点空指针域的浪费:在二叉树的终端结点的指针域有许许多多的NULL,也就是空指针域的存在,这造成了许多的浪费,得想办法利用起来,对于一个有n个结点的二叉链表,每个结点有指向左右孩子的两个指针域,所以是2n个指针域。而n个结点的二叉树一共有n-1条分支线数,也就是说存在2n-(n-1)=n+1个空指针域。②不知道某个结点的前驱和后继:在二叉链表上,我们只能知道...原创 2019-11-01 16:41:37 · 194 阅读 · 0 评论 -
树——二叉树
二叉树的性质:1、在二叉树的第i层上至多有个结点(i>=1)。2、深度为k的二叉树至多有个结点(k>=1)。3、对任何一棵二叉树T,如果其终端结点数为,度为2的结点数为,则=+1。4、具有n个结点的完全二叉树的深度为⌊⌋+1(⌊x⌋表示下取整)。5、如果对一棵有n个结点的完全二叉树(其深度为⌊⌋+1)的结点按层序编号(从第1层到第⌊⌋+1层,每层从左到右),对任一结...原创 2019-10-31 21:40:02 · 165 阅读 · 0 评论 -
串——KMP模式匹配算法修改版
KMP模式匹配算法原版会出现多次回溯问题,所以对于前缀下一个字符和后缀下一个字符相等,则两个字符的nextval值相等,因为这个字符不匹配,回溯后的字符也不匹配,这样一步回溯到位,不用回溯好几次才回溯完,省去多余的重复计算。#include<iostream>using namespace std;#define MaxSize 100typedef struct STR...原创 2019-10-30 20:57:03 · 119 阅读 · 0 评论 -
串——KMP模式匹配算法
朴素模式匹配算法就是简单的二重循环,第一重循环主串S从1到n,然后第二重循环子串T从1到m进行匹配判断,时间复杂度为O((n-m+1)*m)。KMP算法的核心思想是第一、如果子串前r个字符均不相等,且子串前r个字符与主串某连续的r个字符匹配,但子串第r+1就不匹配了,则主串的匹配下标可以直接向前跳r个,因为这r个字符不可能与子串有匹配的了,在代码中体现就是主串下标i不回溯一直+1;第二...原创 2019-10-30 16:47:50 · 198 阅读 · 0 评论 -
队列——链队列
循环队列和链队列的比较:1、从时间上,它们的基本操作都是常数时间,即为O(1)的,不过循环队列是事先申请好空间,使用期间不释放,而对于链队列,每次申请和释放结点也会存在一些时间开销,如果入队出队频繁,则二者还是有细微差异。2、从空间上,循环队列必须有一个固定的长度,所以就有了存储元素个数和空间浪费的问题。而链队列不存在这个问题,尽管它需要一个指针域,会产生一些空间上的开销,但也可以接受,所...原创 2019-10-24 15:00:29 · 247 阅读 · 0 评论 -
队列——循环队列(顺序存储结构)
对于循环队列,也就是队列的顺序存储结构,面临着数组可能溢出的问题,所以还需要研究一下不需要担心队列长度的链式存储结构。循环队列的插入和删除时间复杂度都不高都是O(1),不需要移动队列里面的元素。#include<iostream>using namespace std;#define TRUE 1#define FALSE 0#define MaxSize 100typ...原创 2019-10-23 21:52:36 · 1388 阅读 · 0 评论 -
栈——链栈
对比顺序栈与链栈,他们的时间复杂度是一样的,均为O(1)。对于空间性能,顺序栈需要事先确定一个固定的长度,可能会存在内存空间浪费的问题,但它的优势是存取的定位方便,而链栈则要求每个元素都有指针域,这也增加了一些内存开销,但对于栈的长度无限制。如果栈的使用过程中元素变化不可预料,有时很小有时很大,那么最好是用链栈,反之,如果它的变化在可控范围内,建议使用顺序栈会更好一些。#include<...原创 2019-10-10 21:52:28 · 234 阅读 · 1 评论 -
栈——双端栈(两栈共享空间)
1、使用双端栈通常是当两个栈的空间需求有相反关系时,也就是一个栈增长时另一个栈在缩短的情况。2、双端栈只是针对两个具有相同数据类型的栈的一个设计上的技巧,如果是不相同数据类型的栈,这种办法不但不能更好地处理问题,反而会使问题变得更加复杂。#include<iostream>using namespace std;#define TRUE 1#define FALSE 0...原创 2019-10-09 20:26:51 · 1328 阅读 · 0 评论 -
栈——顺序存储
栈顶指针top指向栈顶元素,初始化的时候栈为空top=-1,出栈和入栈不涉及任何循环所以时间复杂度为O(1)栈的顺序存储还是很方便的,因为它只准栈顶进出元素,所以不存在线性表的插入和删除时需要移动元素的问题,但它有个很大的缺陷就是必须事先确定数组存储空间的大小,万一不够用了,就需要编程的手段扩展数组的容量,非常麻烦。#include<iostream>using name...原创 2019-10-06 11:09:53 · 257 阅读 · 0 评论 -
线性表——双向链表
双向链表的每个结点都需要记录两份指针,所以在空间上要占用略多一些。不过它良好的对称性,使得对某个结点的前后结点的操作,带来了方便,可以有效提高算法的时间性能,说白了,就是用空间换时间。#include<iostream>#include<cstdlib>#include<time.h>using namespace std;#define TRUE...原创 2019-10-01 18:40:53 · 144 阅读 · 0 评论 -
线性表——循环链表
循环链表解决的是如何从当前的一个结点出发,访问到链表的全部结点。在单链表中,有了头结点,可以用O(1)的时间访问第一个结点,但对于最后一个结点访问需要O(n)时间,就是相当于将单链表全部扫描一遍。对于循环列表不用头指针,而是用指向终端结点的尾指针来表示循环链表,也就是最后一个结点就是尾指针作为返回,这样访问头结点就是rear->next,访问终端结点就是rear。#include&...原创 2019-10-01 15:37:32 · 260 阅读 · 0 评论 -
线性表——静态链表
静态链表的优缺点:优点:1、在插入和删除操作时,只需要改变游标cur,不需要移动元素,从而改进了在顺序存储结构中的插入和删除中需要移动大量元素的缺点缺点:1、没有解决连续存储分配带来的表长难以确定的问题2、失去了顺序存储结构随机存取的特性总结:总的来说,静态链表其实是为了给没有指针的高级语言设计的一种实现单链表能力的方法。尽管大家不一定用得上,但这样的思考方式是非常巧妙的,...原创 2019-10-01 12:49:19 · 526 阅读 · 0 评论 -
线性表——单链表
单链表结构与顺序存储结构对比:一、存储分配方式1、顺序存储结构用一段连续的存储单元依次存储线性表的数据元素2、单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素二、时间性能1、查找:顺序存储结构O(1);单链表O(n)2、插入和删除:顺序存储结构O(n);单链表找到位置后插入删除时间O(1)三、空间性能1、顺序存储结构需要预先分配存储空间,分大了浪费,分...原创 2019-09-28 22:02:23 · 179 阅读 · 0 评论 -
线性表——顺序存储
线性表的顺序存储结构时间复杂度:线性表的顺序存储结构,在存、读数据时,不管是哪个位置,时间复杂度都是O(1);而插入或删除元素时,时间复杂度都是O(n);线性表的顺序存储结构优缺点:优点:1、无须为表示表中元素之间的逻辑关系而增加额外的外存空间2、可以快速地存取表中任一位置的元素缺点:1、插入和删除操作需要移动大量元素2、当线性表长度变化较大时,难以确定存储空间的...原创 2019-09-28 18:25:13 · 671 阅读 · 0 评论