
数据结构
文章平均质量分 50
数据结构相关技术分享
优惠券已抵扣
余额抵扣
还需支付
¥99.90
¥299.90
购买须知?
本专栏为图文内容,最终完结不会低于15篇文章。
订阅专栏,享有专栏所有文章阅读权限。
本专栏为虚拟商品,基于网络商品和虚拟商品的性质和特征,专栏一经购买无正当理由不予退款,不支持升级,敬请谅解。
AI算法攻城狮
互联网算法工程师,拥有扎实的理论基础和丰富的算法落地实践经验
展开
-
7.3.2 快速排序
快速排序是对冒泡排序的改进。其基本思想是基于分治法:在待排序L[1...n]中任取一个元素privot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1...k-1]和L[k+1...n],使得L[1...k-1]中所有元素小于privot,L[k+1...n]中所有元素大于或等于privot,则privot最终放在了其最终位置L(k)上,这个过程称作一趟快速排序。而后分别递归地对两个子表重...原创 2015-03-05 09:04:04 · 1305 阅读 · 0 评论 -
斐波那契数列递归算法和非递归算法
斐波那契数列的表达式:F(1)=1F(2)=1F(n)=F(n-1)+F(n-2) (n>2)递归算法:时间复杂度O(n^2)int recursive_method(int n){ if (n == 1 || n == 2) return 1; else return recursive_method(原创 2016-09-18 18:34:26 · 2382 阅读 · 1 评论 -
只有五行的Floyd最短路径算法
暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有,如下图。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。上图中有4个城市8条公路,公路上的数字表示这条公路的长短。请注意这些公路是单向的。我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径。这个问题这也被称为“多源最短路径”问题。现在需要一个转载 2016-02-05 13:37:26 · 1701 阅读 · 0 评论 -
排序算法 归纳总结
一、直接插入排序、冒泡排序和简单选择排序是最基本的排序方法,它们主要用于元素个数n(n它们的平均复杂度均为O(n^2),实现也比较简单。1、直接插入排序对于规模很小的元素序列(n2、冒泡排序在最好的情况下只需要一趟排序过程就可以完成,此时只需要n-1次比较操作,不需要交换操作。3、简单选择排序的关键字比较次数与待排序元素序列的初始排序无关,其比较次数总是O(n^2),但元素移动次数原创 2016-09-09 15:05:33 · 1126 阅读 · 0 评论 -
Dijkstra最短路算法
上篇我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”。本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”。例如求下图中的1号顶点到2、3、4、5、6号顶点的最短路径。与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下。我们还需要用一个一维数组d转载 2016-02-05 17:28:13 · 882 阅读 · 0 评论 -
桶排序算法
一、思想一句话总结:划分多个范围相同的区间,每个子区间自排序,最后合并。桶排序是计数排序的扩展版本,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过映射函数,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序,最后将非空桶中的元素逐个放入原序列中。桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。二、代码import java.util.ArrayList;import java.util.Collection原创 2021-10-01 19:26:56 · 274 阅读 · 0 评论 -
完全二叉树判断,简单而复杂
今天有个人问我如何判断一棵树是完全二叉树。我一下子想不出怎么解决这个问题,按照定义,严蔚敏那本教材上的说法:一个深度为k,节点个数为 2^k - 1 的二叉树为满二叉树。这个概念很好理解,就是一棵树,深度为k,并且没有空位。首先对满二叉树按照广度优先遍历(从左到右)的顺序进行编号。一颗深度为k二叉树,有n个节点,然后,也对这棵树进行编号,如果所有的编号都和满二叉树对应,那么这棵树是完全二叉树。概念我基本上能明白,但是,如何判断我居然写不出来。哎,这样简单的数据结构题,居然不会。于原创 2021-08-28 22:47:51 · 364 阅读 · 0 评论 -
4.3.1 二叉树的遍历
所谓二叉树的遍历,是指按照某条搜索路径访问树中的每个结点,使得每个几点均被访问一次,而且仅被访问一次。遍历一棵二叉树便要决定对根结点N、左子树L和右子树R的访问顺序、按照先序遍历左子树再遍历右子树的原则,常见的遍历次序有先序(NLR)、中序遍历(LNR)和后序遍历(LRN)三种遍历算法。其中,序指的是根结点在何时被访问。1、先序遍历(PreOrder)如果二叉树为空,什么也不做,否则:原创 2016-09-19 11:18:18 · 813 阅读 · 0 评论 -
4.3.2 线索二叉树
二叉树结点的各种遍历序列,其实质是对一个非线性结构进行线性化操作,使在这个访问序列中每一个结点(除第一个和最后一个)都有一个直接前驱和直接后继。传统的链式存储技能体现一种父子关系,不能直接得到结点在遍历中的前驱或后继,通过观察,我们发现在二叉链表表示的二叉树中存在大量的空指针,若利用这些空链域存放指向其直接前驱或后继的指针,则可以更方便地运用某些二叉树操作算法,引入线索二叉树是为了加快查找结点原创 2016-09-19 14:58:17 · 901 阅读 · 0 评论 -
4.5.1 二叉排序树
1、二叉排序树的定义左子树结点值2、二叉排序树的查找二叉排序树的查找时从根结点开始,沿着某一分支逐层向下进行比较比较的过程。若二叉排序树非空,将给定值与根结点的关键字比较,若相等,则查找成功;若不等,则当根结点的关键字大于给定关键字时,在根结点的左子树中查找,否则在根结点的右子树中查找。二叉排序树的非递归查找算法:BSTNode *BST_Search(BiTree T,E原创 2016-09-19 18:45:18 · 1249 阅读 · 0 评论 -
4.5.2 平衡二叉树
1、平衡二叉树的定义为了避免树的高度增长过快,降低二叉排序树的性能,我们规定在插入和删除二叉树结点时,要保证任意结点的左、右子树高度差的绝对值不超过1,将这样的二叉树称为平衡二叉树,简称平衡树(AVL树)。定义结点左子树和右子树的高度差为该结点的平衡因子,则平衡二叉树结点的平衡因子的值只可能是-1、0或1。因此平衡二叉树可定义为它或者是一棵空树,或者是具有下列性质的二叉树:它的左子树和右子原创 2016-09-20 11:35:27 · 986 阅读 · 0 评论 -
4.5.3 哈弗曼树(Huffman)树和哈弗曼编码
1.哈夫曼树的定义树中结点被赋予一个表示某种意义的数值,称为该结点的权。从树根结点到任意结点的路径长度(经过的边数)与该结点上权值的乘积称为该结点的带权路径长度。树中所有叶结点的带权路径长度之和称为该树的带权路径长度,记为WPL=连加Wi*Li式中,Wi是第i个叶结点所带的权值;Ii是该叶结点到根结点的路径长度。在含有N个带权叶子结点的二叉树中,其中带权路径长度(WPL)最小的二叉原创 2016-09-20 14:04:50 · 1326 阅读 · 0 评论 -
5.1 图的基本概念
1、完全图在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。含有n个顶点的无向图有n(n-1)/2条边。在有向图中,如果任意两个顶点之间都存在方向相反的两条弧,则称该图为有向完全图。含有n个顶点的有向完全图有n(n-1)条有向边。2、连通、连通图和连通分量在无向图中,若从顶点v到顶点W有路径存在,则称v和w是连通的。若图G中任意两个顶点都是连通的,则称图G为连原创 2016-09-12 17:14:42 · 934 阅读 · 0 评论 -
5.2 图的存储及基本操作
图的存储必须要完整、准确地反映顶点集和边集的信息。根据不同图的结构和算法,可以用不同的存储方式,但不同的存储方式将对程序的效率产生很大的影响,因此,所选的存储结构应适合于欲求解的问题。无论是有向图还是无向图,主要的存储方式都有两种:邻接矩阵和邻接表。前者属于图的顺序存储结构,后者属于图的链接存储结构。5.2.1邻接矩阵表所谓邻接矩阵存储,就是用一个一维数组存储图中顶点的信息,用一个二维数组存储图中原创 2016-09-13 11:23:47 · 1031 阅读 · 0 评论 -
5.2.2 邻接表法
当一个图为稀疏图时,使用邻接矩阵表示法显然要浪费大量的存储空间。而图的邻接表示法结合了顺序存储和链式存储方法,大大减少了这种不必要的浪费。所谓邻接表就是对每个顶点vi建立一个单链表,第i个单链表中的结点表示依附于顶点vi的边(对于有向图则是以顶点vi为尾的弧),这个单链表就称为顶点vi的边表(对于有向图则成为出边表)。边表的头指针和顶点的数据信息采用顺序存储(称为顶点表),所以在邻接表中存在两原创 2016-09-13 13:41:02 · 1111 阅读 · 0 评论 -
5.2.3 十字链表
十字链表是有向图的一种链式存储结构。在十字链表中,对应于有向图中的每条弧有一个结点,对应于每个顶点也有一个结点,这些结点的结构如下:弧结点taivexheadvexhlinktlinkinfo顶点结点datafirstinfirstout弧结点中有5个域:其中尾域原创 2016-09-13 15:45:32 · 1182 阅读 · 1 评论 -
5.2.4 邻接多重表
邻接多重表时无向表的另一种链式存储结构。在邻接表中,容易求得顶点和边的各种信息,但在邻接表中求两个顶点之间是否存在边,或需要对边执行删除等操作时,需要分别在两个顶点的边表中遍历,效率较低。与十字链表类似,在邻接多重表中,每一条边用一个结点表示,其结构如下图:markivexilinkjvexjlinkinfo其中,mark为标志域原创 2016-09-13 16:18:05 · 3086 阅读 · 0 评论 -
5.3.1图的遍历
图的遍历是指从图中的某一顶点出发,按照某种搜索方法沿着图中的边对图中的所有顶点访问一次且仅访问一次。注意到树是一种特殊的图,所以树的遍历实际上也可以看作是一种特殊图的遍历。图的遍历是图的一种最基本的操作,其他许多操作都建立在图的遍历操作基础之上。5.3.1广度优先搜索(Breadth-First-Search,BFS)广度优先搜索(BFS)类似于二叉树的层序遍历算法,它的基本思想是:首先访原创 2016-09-13 18:27:03 · 1020 阅读 · 0 评论 -
5.3.2 深度优先搜索(Depth-First-Search,DFS)
与广度优先搜索不同,深度优先搜索(DFS)类似于树的先序遍历。正如其名称中所暗含的意思一样,这种搜索所遵循的搜索策略是尽可能“深”地搜索一个图。它的基本思想如下:首先访问图中某一起始顶点v,然后由v出发,访问与v邻接且未访问的任一顶点W1,再访问与w1邻接且未被访问任一W2,……重复上述过程。当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接顶点未被访问过,则从该点开始上述搜索过程,原创 2016-09-14 13:14:34 · 3073 阅读 · 0 评论 -
5.3.3 图的遍历与图的连通性
图的遍历算法可以用来判断图的连通性。对于无向图来说,如果无向图是连通的,则从任一结点出发,仅需一次遍历就能够访问图中所有顶点;如果无向图是非连通的,则从某一个顶点出发,一次遍历只能访问到该顶点所在连通分量的所有顶点,而对于图中其他连通分量的顶点无法通过这次遍历访问。对于有向图来说,若从初始点到图中的每个顶点都有路径,则能够访问图中的所有顶点,否则不能访问到所有顶点。故而在BFSTr原创 2016-09-14 13:33:54 · 2496 阅读 · 0 评论 -
5.4.1 最小生成树(Minimum-Spanning-Tree,MST)
一个连通的生成树是图中的极小连通子图,它包括图中的所有顶点,并且只含尽可能少的边。这意味着对于生成树来说,若砍去它的一条边,就会使生成树变成非连通图;若给它添加一条边,就会形成图中的一条回路。对于一个带权连通无向图G=(V,E),生成树不用,每棵树的权(即树中所有边上的权值之和)也可能不同。设R是G的所有生成树的集合,若T为R中边的权值之和最小的那棵生成树,则T称为G的最小生成树。最小生成原创 2016-09-14 14:04:48 · 1338 阅读 · 0 评论 -
5.4.3拓扑排序
有向无环图:一个有向图中不存在环,则称为有向无环图,简称DAG图。AOV网:如果用DAG图表示一个工程,其顶点表示活动,用有向边表示活动Vi必须先于活动Vj进行的这样一种关系,则将这种有向图称为顶点表示活动的网络,记为AOV网。在AOV网中,活动Vj是活动Vi的直接后继,这种前驱和后继关系具有传递性,且任何活动Vi不能以它自己作为自己的前驱或后继。拓扑排序:在图论中,由一个有向无环图的顶点原创 2016-09-14 17:57:08 · 1066 阅读 · 0 评论 -
5.4.4 关键路径
在带权有向图中,以顶点表示时间,有向边表示活动,边上的权值表示完成该活动的开销(如完成活动所需的时间),则称这种有向图为用边表示活动的网络,简称为AOE网。①只有在某顶点所代表的时间发生或,从该顶点出发的各有向边所代表的活动才能开始。②只有在进入某一顶点的各有向边所代表的活动都已经结束,该顶点所代表的时间才能发生。在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),它表示整个工程原创 2016-09-18 15:41:27 · 1908 阅读 · 0 评论 -
6.2.2 折半查找
折半查找,又称二分查找,它适用于有序的顺序表。基本思路是:首先将给定值key与表中中间位置元素的关键字比较,若相等,则查找成功,返回该元素的存储位置;若不等,则所需查找的元素只能在中间元素以外的前半部分或后半部分中(例如,在查找表升序排列时,若给定值key大于中间元素的关键字,则所查找的元素只可能在后半部分)。然后在缩小的范围内继续进行同样的查找,如此重复直到找到为止,或者确定表中没有搜需要查找的原创 2016-09-18 16:46:40 · 936 阅读 · 0 评论 -
6.3.1 B树及其基本操作
B树,又称多路平衡查找树,B树中所有节点的孩子结点数的最大值成为B树的阶,通常用m表示。一棵m阶B树或为空树,或为满足如下特性的m叉树:1)树中每个结点至多有m棵子树(即至多含有m-1个关键字)。2)若根结点不是终端结点,则至少有两棵子树。3)除根结点外的所有非叶结点至少有【m/2】(向上取整)棵子树(即至少含有【m/2】-1个关键字)4)所有非叶结点的结构如下: n ...原创 2016-08-03 11:07:58 · 4271 阅读 · 4 评论 -
6.3.2 B+树基本概念
B+是应用数据库所需而出现的一种B树的变形树。一棵B+树需满足下列条件:1)每个分支结点最多有m棵子树(子结点)。2)非叶根(不是叶子的根结点)结点至少有两棵子树,其他每个分支结点至少有【m/2】(向下取整)棵子树。(B树是要求至少2棵子树)3)结点的子树个数与关键字个数相等。4)所有叶结点包含全部关键字及指向相应记录的指针,而且叶结点中将关键字按大小顺序排列,并且相邻叶子结点原创 2016-08-22 19:10:52 · 1409 阅读 · 0 评论 -
7.2.1 直接插入排序
算法思想1)查找出L(i)在L[1...i-1]中的插入位置k2)将L[K...i-1]中所有元素全部后移一个位置3)将L(i)复制到L(K)void InsertSort(ElemType A[],int n){ int i,j; for(i=2; i { if(A[i].key原创 2015-03-04 15:09:30 · 1433 阅读 · 0 评论 -
7.2.2 插入排序之折半插入排序
从直接插入排序的过程中,都进行了两项工作:①从前面的子表中查找出待插入元素应该被插入的位置;②给插入位置腾出空间,将待插入元素复制到表中的插入位置。注意到该算法中,总是边比较边移动元素,下面将比较和移动操作分离出来,即先折半查找出元素的待插入位置,然后再统一地移动待插入位置后的所有元素。当排序表为顺序存储的线性表时,可以对直接插入排序做如下改造:由于是顺序存储的线性表,所以查找原创 2016-07-27 13:55:19 · 758 阅读 · 0 评论 -
7.2.3 插入排序之希尔排序
直接插入排序算法适用于基本有序的排序表和数据量不大的排序。基于这两点,1959年D.L.Shell提出了希尔排序,又称为缩小增量排序。希尔排序的基本思想是:先将待排序表分割成若干个形如L[i,i+d,i+2d,...i+kd]的特殊子表,分别进行直接插入排序,当整个表中已呈“基本有序”时,在对全体记录进行一次直接插入排序。希尔排序的排序过程如下:先取一个小于n的步长的d1,把表中全部记录分原创 2016-09-05 19:38:18 · 988 阅读 · 0 评论 -
7.3.1 交换排序之冒泡排序
所谓交换,就是根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。冒泡排序算法的基本思想是:假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值。若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。我们称它为一趟冒泡。结果将最小的元素交换到待排序的第一个位置(关键字最小的元素如气泡一般逐渐往上漂浮,直到水面,这就是冒泡排序名字的由来)。下一趟冒泡时,...原创 2016-09-07 10:48:47 · 1076 阅读 · 0 评论 -
7.4.1简单选择排序
简单选择排序的基本思想是:每趟(例如第i趟)在后面 n-i+1(i=1,2,...,n-1)个待排序元素中选取关键字最小的元素,作为有序子序列的第i个元素,每趟确定一个元素的最终位置,直到第n-1趟做完,待排序元素只剩下1个,就不用再选了。简单选择排序的伪代码:void SelectSort(Elemtype A[],int n){ //对表A进行简单选择排序,A[]原创 2015-02-28 16:26:42 · 1393 阅读 · 0 评论 -
7.4.2 选择排序之堆排序
堆排序是一个树形选择排序方法,它的特点是:在排序过程中,将L[1...n]看成是一棵完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系,在当前无序区中选择关键字最大(或最小)的元素。堆的定义如下:n个关键字序列L[1...n]称为堆,当且仅当该序列满足:①L(i)L(2i)且L(i)>=L(2i+1)(1满足第一种情况的堆称为小根堆(小顶堆),满足第原创 2015-02-28 16:27:53 · 997 阅读 · 0 评论 -
7.5.1 归并排序
归并的含义是将两个或两个以上的有序表组合成一个新的有序表。假定待排序表中含有N个记录,则可以看成是N个有序的子表,每个子表长度为1,然后两两归并,得到[n/2]个长度为2或1的有序表;在两两归并,。。。如此重复,直至合并成一个长度为N的有序表为止,这种排序方法称为2-路归并排序。[49],[38],[65],[97],[76],[13],[27]【38,49】,【65,97】,【7原创 2015-03-05 16:25:45 · 1013 阅读 · 0 评论 -
7.5.2 基数排序
基数排序是一种很特别的排序方法,它不是基于比较进行排序的,而是采用多关键字排序思想,借助“分配”和“收集”两种操作对单逻辑关键字进行排序。基数排序又分为最高位优先(MSD)排序和最低位优先(LSD)排序。以r为基数的最低位优先基数排序的过程:假设线性表由结点序列a0,a1,……an-1构成,每个结点aj的关键字由d元组[{ k((d-1j),k(d-2,j),……,k(1,j),k(0,j原创 2016-09-07 13:17:50 · 875 阅读 · 0 评论 -
7.6.1 内部排序算法的比较
算法种类最好情况平均情况最差情况空间复杂度是否稳定直接插入排序O(n)O(n^2)O(n^2)O(1)是冒泡排序O(n)O(n^2)O(n^2)O(1)是简单选择排序O(n^2)O(n^2)O(n^2)O(1)否希尔排序 O(1)否快速原创 2015-12-05 00:27:06 · 1295 阅读 · 0 评论 -
7.6.2 内部排序算法的应用
(1)选取排序方法需要考虑的因素1)待排序的元素数目n。2)元素本身信息量的大小。3)关键字的结构及其分布情况。4)稳定性的要求。5)语言工具的条件,存储结构及辅助空间的大小等。(2)排序算法小结1)若n较小(N2)若文件的初始状态已按关键字基本有序,则选用直接插入或冒泡排序为宜。3)若n较大,则应采用时间复杂度为O(nlog2N)的排序方法:快速排序、堆排序或原创 2016-09-08 19:09:32 · 727 阅读 · 0 评论 -
7.7.1外部排序
①外部排序指待排序文件较大,内存一次放不下,需存放在外部介质的文件的排序。②为减少平衡归并中外存读写次数所采用的方法:增大归并路数和减少归并段个数。③利用败者树增大归并路数。④利用置换-选择排序增大归并段长度来减少归并段个数。⑤由长度不等的归并段,进行多路平衡归并,需要构造最佳归并树。7.7.1外部排序的基本概念内部排序都是在内存中进行的,而在实际应用中,经常需要对大文件进原创 2016-09-09 15:28:32 · 769 阅读 · 0 评论 -
7.7.3 多路平衡归并与败者树
归并趟数S=[logm R](向下取整)。从而增加归并路数m可以减少归并趟数S,进而减少访问外存的次数(I/O次数)。然而,当增加归并路数m时,内部归并时间将增加。做内部归并时,在m个元素中选择关键字最小的记录需要比较m-1次。每趟归并n个元素需要作(n-1)*(M-1)次比较,S趟归并总共需要的比较次数为:S*(n-1)*(m-1)=[logmR]*(n-1)*(m-1)=[log2R]*(原创 2016-09-09 18:59:49 · 4369 阅读 · 1 评论 -
7.7.4 置换选择排序(生成初始归并段)
7.7.3讨论了如何使用m路归并来减少磁盘访问次数。从第7.7.2的讨论可知,减少初始归并段个数r也可以减少归并趟数S。若总的记录个数为n,每个归并段的长度为L,则归并段的个数m=[n/L]。如果采用前面介绍的内部排序方法,将得到长度相同的初始归并段。因此,必须探索新的算法俩生成初始归并段,这就是本节介绍的置换-选择算法。设初始待排文件FI,初始归并段文件为FO,内存工作区为WA,内存工作区可原创 2016-09-12 11:24:33 · 8282 阅读 · 0 评论 -
7.7.5 最佳归并树
文件经过置换-选择排序之后,得到的是长度不等的初始归并段。下面讨论如何组织初始归并段的归并顺序,使I/O访问次数最少。m-路归并排序可用一棵m叉树描述,因为每一次作m路归并都需要m个归并段参加,因为,归并段树是一棵只有度为0和度为m的结点的严格m叉树。设由置换-选择排序得到9个初始归并段,其长度(记录数)依次为:9,30,12,18,3,17,2,6,24。现作3-路归并,各叶结点表示原创 2016-09-12 14:45:43 · 10078 阅读 · 0 评论