![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构
文章平均质量分 73
爬比我。
这个作者很懒,什么都没留下…
展开
-
并查集实现
void initialise(int parents[]){ for (int i = 0; i < mmm; i++) { parents[i] = -1; }}int find_root(int x, int parents[]){ int x_root = x; while (parents[x_root] == -1) { x_root = parents[x_root]; } return x_root;}int unionn(int x, int.原创 2021-01-15 20:34:21 · 104 阅读 · 0 评论 -
分支限界算法。
分支限界法类似于回溯算法,是在问题的解空间树上搜索问题解的算法,主要体现在两点不同:1.求解目标不同。回溯算法的求解目标是找出解空间树中满足约束条件的所有解,而分支限界法的求解目标是找出满足约束条件的一个解,或者是在满足约束条件的解中找出某种意义下的最优解。⒉.搜索解空间树的方式不同。回溯算法以深度优先的方式搜索解空间树,而分支限界法则以广度优先或者以最小耗费优先的方式搜索解空间树。分支限界算法基本思想:分支限界法常以广度优先或以最小耗费(最大效益)优先的方式搜索问题的解空间树。在分支限界法中,每一原创 2020-11-10 11:25:50 · 1161 阅读 · 1 评论 -
贪心算法
当一个问题具有最优子结构性质时,可以使用动态规划法求解,但有时候使用贪心算法更简单,更直接而且解决问题的效率很高。 当一个问题具有最优子结构性质时,可以使用动态规划法求解,但有时候使用贪心算法更简单,更直接而且解决问题的效率很高。贪心算法总是做出在当前看来最好的选择,也就是说贪心算法并不从整体最优考虑,它所做出的选择只是在某种意义上的局部最优选择,当然最终希望贪心算法得到的最终结果也是最优的。 例如前面动态规划算法中的硬币问题就可以用贪心算法来解决,从算法名字上来看,贪心算法总是做出在当前看来最好的选择,也原创 2020-11-09 19:19:15 · 162 阅读 · 0 评论 -
动态规划
动态规划算法的思想基本思想与分治算法类似,也是将待求解的问题划分为若干个子问题,按照划分的顺序求子阶段问题。前一个子问题的解,为后一个子问题求解提供了有用的信息。在求解任意子问题时,列出各种可能的局部解,通过决策保留可以达到最优的局部解,丢弃其它局部解。依次解决各个子问题,最后求出原问题的最优解。其与分治算法最大的区别是:适用于动态规划算法的求解问题,经分解后得到的子问题往往不是相互独立的。动态规划求解问题的基本步骤:动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间原创 2020-10-17 20:54:38 · 120 阅读 · 0 评论 -
分治算法
分治算法的思想分治算法的思想就是分而治之,比如规模为n的原问题的解无法直接求出,进行问题规模的缩减,划分子问题。如果子问题的规模仍然不够小,再进行子问题划分,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止,最后将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。分治算法适用条件1.原问题的规模缩小到一定的程度就可以容易地解决⒉原问题可以分解为若干个规模较小的相同问题,即原问题具有最优子结构性质3.利用原问题分解出的子问题的解可以合并为原问题的解4.原创 2020-10-11 23:33:17 · 195 阅读 · 0 评论 -
一篇博客让你跟深入了解回溯算法
回溯算法的思想1.回溯算法就是一种有组织的系统最优化搜索技术,可以看作蛮力法穷举搜索的改进。回溯法常常可以避免搜索所有可能的解,所以它适用于求解组织数量较大的问题。2.首先我们先了解一下一个基本概念“解空间树”:问题的解空间一般使用解空间树的方式来组织,树的根节点位于第1层,表示搜索的初始状态,依次向下排列。3.解空间树的动态搜索:在搜索至树中任一节点时,先判断该节点对应的部分是否是满足约束条件,或者是否超出目标函数的界,也就是判断该节点是否包含问题的最优解。如果肯定不包含,则跳过对该节点为根的原创 2020-10-03 22:01:29 · 227 阅读 · 0 评论 -
B树、B+树与B*树
首先我们来看一下AVL树,AVL树是一个二阶的平衡树,一个节点有两个地址域,有一个数据域。B-树在大规模数据存储中,实现索引查询这样一个实际背景下,树节点存储的元素数量是有限的(如果元素数量非常多的话,查找就退化成节点内部的线性查找了),这样导致二叉查找树结构由于树的深度过大而造成磁盘I/O读写过于频繁,进而导致查询效率低下,那么如何减少树的深度,一个基本的想法就是:采用多叉树结构(由于树节点元素数量是有限的,自然该节点的子树数量也就是有限的)。这样我们就提出了一个新的查找树结构——多路查找树。原创 2020-09-23 20:48:12 · 963 阅读 · 1 评论 -
红黑树的插入与删除
红黑树的性质:红黑树每一个节点都是有颜色的,不是黑色就是红色。 根节点必须为黑色。 所有叶子节点都为黑色,叶子节点是null,不存储实际数据。 每个红色的节点必须要有两个黑色的子节点,或者说每个叶子结点到根节点的所有路径上不能有连续的红色节点。 从根节点开始到任意叶子节点的路径上,黑色节点的数量必须是一致的。 节点的左右高度差最多不能超过两倍。...原创 2020-09-22 00:08:21 · 411 阅读 · 0 评论 -
查找算法
目录折半查找线性索引查找折半查找折半查找又称为二分查找,它的前提是记录的关键码有序,线性表必须采用顺序存储。折半查找的思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找...原创 2020-02-19 20:15:06 · 729 阅读 · 0 评论 -
最小生成树 普里姆算法
构造成连通网的最小代价生成树(MinimumCostSpanningTree)称为最小生成树(简称MST)。找连通网的最小生成树,经典的有两种算法,普里姆算法和克鲁斯卡尔算法。普里姆(Prim)算法对于图中的网来看,找出了它所有的生成树,其中T3和T5的各边权值之和最小,所以T3和T5都是最小生成树,可见最小生成树不一定为1。普里姆算法思想:假设N= (P;{E}) 是连通......原创 2020-02-15 11:56:24 · 3962 阅读 · 1 评论 -
图的遍历 深度优先遍历 广度优先遍历
图的遍历和树的遍历类似的,从图中某一顶点出发遍访图中其余顶点,且使每个顶点只被访问一次,这个过程叫做图的遍历。图那么复杂,因为它的任一顶点都可能和其余的所有顶点相邻接,极有可能存在沿着某条路径搜索后,又回到原顶点,而有些顶点却还没有遍历到的情况。因此我们需要在遍历过程中把访问过的顶点打上标记,以避免访问多次而不自知。具体办法是设置-一个访问数组 visited[n], n是图中顶点的个数,初值......原创 2020-02-14 21:13:46 · 3170 阅读 · 0 评论 -
图的存储结构
由于图的结构比较复杂,任意两个顶点之间都可能存在联系,因此图不可能用简单的顺序存储结构来表示。那么我们来看一下如何去表示一个复杂关系的图。1.邻接矩阵数组表示法:用两个数组分别存储数据元素(顶点)的信息和数据元素之间的关系。图的邻接矩阵存储方式是用两个数组来表示图,一个一维数组存储图中顶点的信息,一个二维数组(称为邻接矩阵)存储图的边或弧的信息。无向图的边数组是一个对称矩阵。如下图表示......原创 2020-02-14 12:59:52 · 3228 阅读 · 0 评论 -
图的定义
图的定义图:图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G (V,E ),其中, G 表示一个图, V 是图 G 中顶点的集合, E 是图 G 中边的集合。如图:对于图的定义,我们需要明确几个注意的地方。线性表中我们把数据元素叫元素,树中将数据元素叫结点 ,在图中数据元素,我们则称之为顶点 (Vertex) 。 线性表中可以没有数据元素,称为空表。树中可以没有......原创 2020-02-13 21:08:14 · 2212 阅读 · 0 评论 -
赫夫曼树(最优二叉树) 赫夫曼编码
首先我们看一下相关的一些概念。路径长度:从树中一个节点到另外一个节点之间的分支构成两个节点之间的路径,,路径上的分支数目称为路径长度。如图中的数字就为路径长度。树的路径长度就是从树根到每一个节点的路径的长度总和。上图二叉树的树路径长度为1+1+2+2+2+2+3+3=16。那么根据这样可以得出当节点一样的两棵树,完全二叉树时其树路径长度最小。当为单叉树树时其树的路径长度最大。带权路......原创 2020-02-13 14:13:25 · 3186 阅读 · 0 评论 -
二叉树的遍历 前序遍历 中序遍历 后序遍历 层序遍历
目录1.前序遍历2.中序遍历3.后序遍历4.层序遍历二叉树的遍历是指从根节点出发, 按照某种次序依次访问二叉树中所有结点, 使得每个结点被访问一次且仅被访问一次。二叉树的遍历方式很多,如果我们限制了从左到右的习惯方式,那么主要就分为四种:1.前序遍历前序遍历的规则是若二叉树为空,则空操作返回,否则先访问根结点,然后前序遍历左子树,再前序遍历右子树。如图所示的二叉树遍历的...原创 2020-02-10 13:21:30 · 1354 阅读 · 0 评论 -
二叉树
树:树是n(n>=0)个节点的有限集。n=0是称为空树。在任何一颗非空树中:(1)有且仅有一个特定的节点称为根节点;(2)当n>1时,其余节点可分为m(m>0)个互不相交的有限集T1、T2、、、Tm,其中每一个集合又是一棵树。如图:接下来看二叉树!!!二叉树:每个结点至多只有两颗子树(即二叉树中不存在度大于2的结点),并且,二叉树的子树有左右之分,其次序不能任意颠倒。......原创 2020-02-09 21:39:58 · 1515 阅读 · 0 评论 -
KMP算法
KMP算法:KMP是由3个外国人想出来的设计的线性时间字符串匹配算法。时间复杂度很低O(n),是判定字串的一个十分简便的方法。KMP算法在搜索发生失配时,将模式串向右滑动到某个位置重新开始匹配而不是回溯,提高了搜索效率。经过分析,KMP算法的时间复杂度为O(m+n),暴力搜索算法的时间复杂度为O(mn),KMP算法的搜索效率远远高于暴力搜索算法。我们采用了一个next数组来解决该问题。KM...原创 2020-02-03 23:15:01 · 1160 阅读 · 0 评论 -
队列的实现
队列,和栈一样,也是一种对数据的"存"和"取"有严格要求的线性存储结构。队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。栈有顺序存储和链式存储,那么队列也有顺序存储和链式存储。与栈不同的是,队列元素的出列是在队头,即下表...原创 2020-01-31 13:46:13 · 788 阅读 · 0 评论 -
栈的应用
根据之前链式栈的实现方法来实现栈的应用。https://blog.csdn.net/qq_41078889/article/details/103941387目录1.进制转换2.括号匹配问题3.四则运算表达式求值1.进制转换进制转换的过程中,我们用短除法得到余数,然后最后将余数倒过来写,这个和栈的后进先出的原理一致,所以可以使用栈实现。将每次得到的余数都压入栈中,当除完到最...原创 2020-01-14 22:06:14 · 445 阅读 · 0 评论 -
栈的实现
栈:一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。我们把允许插入和删除的一端称为栈顶(top),另一端 称为栈底(bottom)。不含任何数据元素的栈称为空栈。栈是一种先入后出的线性表。压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫出栈,出数据在栈顶。在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈...原创 2020-01-14 18:04:38 · 1139 阅读 · 0 评论 -
双向链表
在单链表中,我们有了next指针,这就使得我们要查询的下一个节点的时间复杂度为O(1),可是我们要找的是上一个节点的话,那么最坏的情况就是O(n)了,因为我们每次都要从头开始查找。为了改善查找的时间复杂度,就有了现在的双向链表。双向链表:就是在单链表的每个节点中加入一个指向其前驱的指针域。所以在双向链表的每个节点中存在两个指针域,一个指向前驱,一个指向后继。双向链表的实现基本上与单链表...原创 2019-12-08 13:15:32 · 1101 阅读 · 0 评论 -
不带头结点的单链表
不带头结点的单链表是以一个指针来存储第一个结点的位置,相当于带头结点单链表的头结点只存储地址而不存储目前的结点个数。插入删除和带头结点的链表不一样外,其它功能基本相似。#include<stdio.h>#include<assert.h>#include<stdlib.h>typedef struct Node{ int data; str...原创 2019-12-03 19:58:31 · 1644 阅读 · 0 评论 -
单链表是否相交的问题
单链表相交分为三种情况。两个链表相交且都不带环//单链表相交1Node* IsCross_NoCycle(List list1, List list2){ assert(list1 && list2); int len1 = length(list1); int len2 = length(list2); Node* longlist; Node* sho...原创 2019-11-26 11:00:58 · 776 阅读 · 0 评论 -
单链表有环、无环、环的长度
问题:给你一个单链表,需要找到一个方法进行判断是否有环的存在。双指针判断单链表是否有环;使用两个slow, fast指针从头开始扫描链表。指针slow 每次走1步,指针fast每次走2步。如果存在环,则指针slow、fast会相遇;如果不存在环,指针fast遇到NULL退出。存在环就会导致两个指针(slow和fast指针)一定会相遇。显然这个链表是有环的,蓝色部分是单链表的环...原创 2019-11-24 19:31:32 · 899 阅读 · 0 评论 -
单链表逆置、排序、合并、约瑟夫环问题
单链表的基本实现:https://blog.csdn.net/qq_41078889/article/details/90603873以下这些功能的实现依赖上一篇博客单链表的基本实现(有头结点)。单链表的排序(冒泡) 单链表的倒数第K个值(只能遍历一遍单链表) 逆置单链表 两个单链表的合并问题 单链表的约瑟夫环问题1.单链表的排序(冒泡)对单链表的数据从小到大进行排序,根据冒......原创 2019-11-24 14:53:33 · 1249 阅读 · 0 评论 -
BST树(二叉查找树)C++的实现
二叉查找树(Binary Search Tree),也称二叉搜索树、有序二叉树(ordered binary tree),排序二叉树(orted binary tree),是指一棵空树或者具有下列性质的二叉树:若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 任意节点的左、右子树也分别为二叉查找树;......原创 2019-05-28 21:57:52 · 1746 阅读 · 1 评论 -
单链表的头插尾插删除添加
单链表:单向链表是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始。链式存储结构的线性表将采用一组任意的存储单元存放线性表中的数据元素。由于不需要按顺序存储,链表在插入、删除数据元素时比顺序存储要快,但是在查找一个节点时则要比顺序存储要慢。使用链式存储可以克服顺序线性表需要预先知道数据大小的缺点,链表结构可以充分利用内存空间,实现灵活的内存动态管理。但是链式存储失去...原创 2019-05-27 15:47:34 · 1240 阅读 · 0 评论 -
线性表
线性表:零个或多个元素的有限序列。线性表顺序存储的缺点:在删除和添加元素时会移动大量元素,效率低下。#include<stdio.h>#include<assert.h>#define SIZE 10typedef struct Sqlist{ int elem[SIZE]; int usedsize;}Sqlist,*PSqlist; //...原创 2019-05-24 18:54:56 · 373 阅读 · 0 评论