
数据结构
文章平均质量分 65
又秃又弱
博客主要记录和分享本人学习,请斟酌帖子,勿一味的输入知识
展开
-
什么是BST二叉排序(搜索)树?
引言:对于有序的查找,查找可以用折半、插值、斐波那契等查找算法来实现,找到后返回该位置,没找到插入到该位置,但是插入的话把后面元素全部后移,因为有序,在插入和删除操作上,就需要耗费大量的时间。无序的查找更是麻烦。而二叉排序树就是一种既可以使得插入和删除效率不错,又可以比较高效率地实现查找的算法一、概念1.定义BST--二叉排序树(二叉搜索树)要么是空树,要么是具有下列性质的二叉树BST的优点:不是仅仅为了查找,还为了插入元素和删除元素的方便(插入和删除不用移动)在查找时,没有节点->插入。原创 2023-04-24 11:03:43 · 348 阅读 · 0 评论 -
拓扑排序的思想?用代码怎么实现
从入度为0的顶点开始访问,访问完成后,将以此顶点为狐尾的弧删除(此顶点的邻接表中的顶点入度都减少1),然后继续查找剩余顶点中入度为0的顶点,重复操作,直到所有顶点都被访问完,或者没有了入度为0的顶点(说明此AOV有回路)构造时会有两个结果,如果此网的全部顶点都被输出,则说明它是不存在环(回路)的AOV 网,如果输出顶点数少了,哪怕是少了一个,也说明这个网存在环(回路),不是AOV 网。拓扑排序的价值在于,不存在回路的AOV 网,我们可以将它应用在各种各样的工程或项目的流程图中,满足各种应用场景的需要。原创 2023-02-22 11:48:32 · 625 阅读 · 0 评论 -
什么是最小生成树?Prim和kruskal算法是什么?
在下图中, 显然是一个带权值的图,即网结构。假设每个结点是一个村,要使村之间能够互相通信,8个存最少需要的边个数为7(n个顶点最少需要n-1条边将其连通起来)。n 个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小,就是各村之间通信的最小成本,每多一公里就多一份成本,所以只要让线路连线的公里数最少,就是最少成本了。把构造连通网的最小代价生成树称为最小生成树MSpanningTree)。而构建最小生成树共有两种算法——prim算法和kruskal算法,在下面进行介绍。原创 2023-02-08 21:52:06 · 408 阅读 · 0 评论 -
深度搜索和广度搜索是什么?代码怎么实现?
对下左图进行如右图的深度搜索:从顶点A开始遍历,接着遍历A的第一个邻接顶点继续从B开始遍历B的第一个邻接顶点C,接着从C始遍历C的第一个邻接顶点D...直到遍历到F,F的第一个临界顶点已经被遍历,则遍历F的下一个邻接顶点G,接着从G的第一个邻接顶点遍历。对下左图进行广度搜索: 从顶点A开始遍历,接着遍历A的第一个邻接顶点B继续从B开始遍历B的第一个邻接顶点C,接着从C开始遍历C的第一个邻接顶点D.直到遍历到F,F的第一个临界顶点已经被遍历,则遍历F的下一个邻接顶点G,接着从G的第一个邻接顶点遍历。原创 2023-02-07 19:38:55 · 2031 阅读 · 0 评论 -
【图】什么是图?无向图怎么存储?邻接表和邻接矩阵如何用代码存储图?
图按照有无方向分为无向图和有向图。无向图由顶点和边构成,有向图由顶点和弧构成。弧有弧尾和弧头之分。图按照边或弧的多少分稀疏图和稠密图。如果任意两个顶点之间都存在边叫完全图,有向的叫有向完全图。若无重复的边或顶点到自身的边则叫简单图。图中顶点之间有邻接点、依附的概念。无向图顶点的边数叫做度,有向图顶点分为入度和出度。图上的边或弧上带权则称为网。图中顶点间存在路径,两顶点存在路径则说明是连通的,如果路径最终回到起始点则称为环,当中不重复叫简单路径。若任意两顶点都是连通的,则图就是连通图,有向则称强连通图原创 2023-02-01 22:05:57 · 2501 阅读 · 0 评论 -
C语言实现哈夫曼编码
一般地,设需要编码的字符集为{ d,_,.",dn }, 各个字符在电文中出现的次数或频率集合为{ W1,W2,..,Wn},以{d1,d2..,dn}作为叶子结点,以W1,W2...,Wn作为相应叶子结点的权值来构造一棵赫夫曼树。规定赫夫曼树的左分支代表0,右分支代表1,则从根结点到叶子结点所经过的路径分支组成的0和1的序列便为该结点对应字符的编码,这就是。编码中非0即1,长短不等的话其实是很容易混淆的,所以若要设计长短不等的编码,则必须是任一字符的编码都不是另一个 字符的编码的前缀,这种编码称做。原创 2022-11-22 20:42:49 · 199 阅读 · 0 评论 -
八大排序之插入排序
插入排序:(小的往前走)思想:无序序列: 4 2 3 5 7 1 9 2 0 i j //i、j对应指向上面的数字(不知道箭头符号在哪就没有画出来) temp=2(j)4>2,4后移 j++ 2 4 3 5 7 1 9 2 0 //标红为已排序 i j //i之前有序 ......原创 2021-12-16 21:28:59 · 70 阅读 · 0 评论 -
利用栈将中缀表达式转换为后缀表达式
我们正常平时使用的表达式是中序/中缀表达式,即运算符在数字中间,中缀的缺点:需要考虑符号的优先级。遇到运算符,弹出两个栈顶元素进行运算,最上面的栈顶元素作为运算符右边,第二个栈顶元素位于运算符左边。小括号的处理:左一定进,右一定不进,直到出栈时,右小括号遇上左小括号,相互抵消。2.运算符之间入栈和出栈依赖优先级情况,优先级高的就入栈,低的就先将栈内高优先级出栈后进行入栈。同样的运算符,栈内的优先级比待入栈运算符优先级低,先入栈的优先级高。1.对表达式进行扫描,遇到运算符时就入栈,数字就不管。原创 2022-11-22 20:44:08 · 1667 阅读 · 0 评论 -
203移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回新的头节点。示例:输入:head = [1,2,6,3,4,5,6], val = 6输出:[1,2,3,4,5]原创 2022-11-25 14:31:01 · 94 阅读 · 0 评论 -
括号匹配 用栈实现
实现对括号的匹配,首先对接收到的字符判断是否是左括号,如果是进行入栈,否则就对右括号和栈顶的值进行判断,如果不相等,则不满足括号匹配。原创 2022-11-19 16:50:12 · 193 阅读 · 0 评论 -
234回文链表的实现 利用栈解决
力扣 234题。原创 2022-11-19 16:25:46 · 280 阅读 · 0 评论 -
【栈】链式栈知识点-内含基本操作及其说明
储叫做顺序栈,栈的链式存储叫做链式栈,简称链栈对于链栈,基本不存在栈满的情况,不用像顺序栈一样判满然后扩容。空战就是链表头结点指向空,即plist->next==NULL顺序栈需要事先确定一个固定的长度,可能会存在内存浪费的问题,但是它的优势是存取时定位很方便,而链栈则要求每个结点有个指针域。但是链栈大小很灵活,最好使用链栈。栈顶的位置由哪端就在哪端决定,发现在栈顶进行插入删除操作,因此栈顶位置在表头头插头删:O(1)尾巴:O(n)链式栈其实就是把顺序表改为链式结构顺序栈:栈顶在尾巴链式栈原创 2022-11-19 12:15:44 · 1205 阅读 · 0 评论 -
【链表】删除倒数第K个点代码及原理
删除一个结点的做法是让该结点的前驱直接指向该节点后继。因此,需要找到k前驱法一:思考倒数第k个点是正数第几个点?倒数第k=顺数第len-k+1个点法二:快慢指针法则。快指针先走k步,然后快慢指针一起走。当快指针->next为空的时候,慢指针所在结点就是倒数第k个点的前驱。方法一:方法二快慢指针(双指针法)(常用)原创 2022-11-09 17:43:45 · 312 阅读 · 0 评论 -
【链表】判断链表是否有环-快慢指针
一个结点有两个指向的时候就会产生环。例如在一个单链表0-9的数据中,3的下个节点为4,让3的下个结点同时指向9,此时就会在3的位置产生两条路,一个指向9,一个指向4,这就是有环的情况。,如果有环,快慢指针会在环内,永远不会到达空的位置,会陷入死循环。让3的下个结点指向9,构造有环的第二批数据:有环。0-9的第一批数据:无环。原创 2022-11-05 11:49:32 · 588 阅读 · 0 评论 -
【链表】链表逆置/反转链表 如何用递归和非递归实现?
将原链表断开,然后把头结点的下一个结点位置的值依次进行头插在头结点后面,用下图示例:1.首先把plist断开:plist->next=NULL;2.把p头插在plist链后面://p=NULL//plist->next=500,500是p结点的地址3.把p重新赋值为q的位置,q后移一个:p=q;把p继续进行头插到plist后面:p->next=plist->next;重复操作,一直到最后q=NULL,p=q=NULL时停下。原创 2022-11-04 08:58:55 · 723 阅读 · 0 评论 -
【顺序表】知识点(含代码实现)
存储结构存储空间的起始位置:数组elem,他的存储位置就是存储空间的存储位置。线性表的最大存储容量:数组长度MaxSize线性表的当前长度:length数据长度和线性表长度的区别数组的长度是存放线性表的存储空间的长度,存储分配后诸葛亮一般是不变化的。但是可以用变成手段实现动态分配内存。线性原创 2022-10-23 16:05:19 · 588 阅读 · 0 评论 -
八大排序之希尔排序
【代码】八大排序之希尔排序间隔式分组,然后利用直接插入排序让组内数据有序,再缩小分组,再排序,在缩小分组,直到缩为1组原创 2022-09-13 20:01:32 · 342 阅读 · 0 评论 -
八大排序之直接插入排序
如果小循环内的j所在数据大于temp,就把arr[j]->arr[j+1],否则,就说明当前arr[j]arr[i]标记当前i的数据,大循环往后走。四、时间复杂度与空间复杂度。原创 2022-09-13 19:14:13 · 272 阅读 · 0 评论 -
八大排序之归并排序
思想将两段有序的数据合并成一段更有序的数据,把两段有序的归并为一段更有序的也叫做二路归并原创 2022-09-13 17:08:52 · 221 阅读 · 0 评论 -
恢复二叉树思路及代码
重复3)步骤,找到右子树的根c,在中序遍历中将c的左子树f,右子树g找到。1)找中序内和先序第一个相等的根:a。2)先序遍历中,从根a后面找3个。划分左子树: b是左子树的根,从中序遍历中找到根B,b左边是左子树,右边是右子树。1)后序中最后一个字符a为根。先序:(根、左、右)a b d e c f g。中序:(左、根、右)d b e a f c g。后序:(左、右、根)d e b f g c a。以下图二叉树为例进行思路演示。vlr: 从先序遍历走。lvr: 从中序遍历走。n: 当前字符串个数。...原创 2022-08-12 15:41:43 · 440 阅读 · 0 评论 -
C语言实现Huffman哈夫曼树的创建
哈夫曼编码:左分支赋值为0,右分支赋值1(前提是待编码的树为哈夫曼树)结点的路径长度:从树根到分支的A:1。树的路=路径长度: A:5 B:15。树:每一个结点的带权路径之和。带权路径最小的为哈夫曼树。...原创 2022-08-12 13:28:11 · 586 阅读 · 0 评论 -
在二叉树中查找K值
Node* Create(const char*& str) //因为要修改字符串就加了引用&printf("找到了!//指向当前节点右孩子指针。//指向当前节点左孩子指针。printf("未找到了!char value;找到了返回该结点,未找到返回空。//在二叉树中查找某值的结点。//先序遍历创建二叉树。......原创 2022-08-09 22:33:26 · 565 阅读 · 0 评论 -
计算二叉树的高度/深度
左子树B的高度是左子树D与右子树(该图右子树无)的高度 求两者最大值 然后+1。树中结点的最大层次称为树的深度(Depth)或高度,当前树的深度为5。右子树C的高度是左子树E与右子树F的高度 求两者最大值 然后+1。计算A的左子树B的高度与右子树C的高度 求两者最大值 然后+1。. . .(每颗子树都能再拆分为新子树求,递归实现)直至待访问的子树为空树。...原创 2022-08-09 22:21:30 · 1897 阅读 · 0 评论 -
计算二叉树中结点的个数
二叉树中结点的个数:只要能计算出A左子树的个数+A右子树的个数+1。左子树个数:以B为结点的左子树个数+右子树个数+1。右子树个数:以C为结点的左子树个数+右子树个数+1。. . . .(每颗子树都能再细分拆为子树)图示为举例二叉树进行思路解释。直到待访问的子树为空树。...原创 2022-08-09 21:33:21 · 9377 阅读 · 0 评论 -
C语言-- 用队列实现栈的功能以及用栈实现队列
1)定义两个队列:Temp、data。临时队列temp: 先进的数据放在这。然后从data内移到temp。原创 2022-08-09 20:28:03 · 465 阅读 · 0 评论 -
【二叉树】遍历与创建 前序中序后续 递归实现
第二次遇到*: * * * * C E * J * * F * *,形成如下图所示的二叉树,将I的左右孩子赋值为NULL后,向上走,顺次该对H的右孩子赋值为NULL,然后对B的右孩子赋值为NULL,紧接着将C赋值到A的右孩子位置...第一次遇到 * :* * H I * * * * C E * J * * F * *,形成如下图所示的二叉树,将G的左右孩子赋值为NULL后,向上走,顺次该对D的右孩子赋值...原始数据:A B D G * * H I * * * * C E * J * * F * *....原创 2022-08-08 09:36:57 · 1417 阅读 · 0 评论 -
【二叉树】层次遍历 队列实现
/出队头元素d,d无左右孩子,继续出队头元素e,e无左右孩子,继续出队头元素f。那么问题来了:此时应该遍历c 但是c被压在栈底出不来,只能先访问d和e,入栈顺序:根 右 左 //必须通过根节点去保存左右孩子。② 判断树是否为空,不为空,则队头元素进行入出队。//c还未出队所以还在,然后入b的左右孩子de。//de还未出队所以还在,然后入c的左右孩子fg。//出队头元素g,g无左右孩子,继续出队头元素h。//首先判断树是否为空,不为空,则入树根a。//先入a的左孩子b,再入a的右孩子c。......原创 2022-08-08 09:20:48 · 379 阅读 · 0 评论 -
用栈进行非递归实现前中后遍历二叉树
/a出栈后,p=a的右孩子,p指向c,进入外while循环满足条件进入内while循环,依次找到最左端结点,期间将c f h依次入栈内,直到h结点无左孩子,p=NULL,退出内while1循环,进入if条件内。//首先p指向根节点a进行循环查找该子树的最左端数值d,途中b入队,d入队后发现此时d无左孩子,p=NULL,退出内while循环,进入if函数。//先入根节点a,然后根、右、左的顺序将c b入栈,然后b作为栈顶元素,按照右、左的顺序将e d入栈,栈顶元素d既无左孩子又没右孩子,开始出栈。......原创 2022-08-08 09:19:22 · 542 阅读 · 0 评论 -
树与二叉树的基本概念
在任意一棵非空树中: (1)有且仅有一一个特定的称为根(Root) 的结点: (2)当n>1时,其余结点可分为m (m>0)个互不相交的有限集T1、T2、...*. T.其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。简便来说,n=0时为空树,n≠0,一个树有且只有一个根,其他的都是子树,子树之间是不相交的。(Binary Tree)是n(n≥0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。...原创 2022-08-08 09:34:14 · 239 阅读 · 0 评论 -
八大排序之堆排序
原始数据749512683102311。调整后为231291011683547。下标从0开始作为二叉树的根节点,数据从上到下依次赋值,父子。父子结点关联(下标从0开始)每次调整后从上往下再调一遍。从后往前(从下往上)调整。......原创 2022-08-01 16:56:24 · 136 阅读 · 0 评论 -
八大排序之选择排序
思想:i:即将要放的位置下标,从0地址开始依次向后走j:从初始位置依次遍历查找最小值min:先赋第一个值为初值,通过一个个比较,更替最小值minminIndex:保存最小值的下标//minIndex存在的意义:当查找到当前无序序列中最小值min后,如果直接将min与i位置交换,会导致原序列改变(eg:123045->023045,min=1)从有序序列内选出最小序列,将最小的放到最前面(放到i处),j目前为当前下标,与min比较。找到最小值后,保存下标,i与min交换,原创 2021-12-02 10:46:42 · 98 阅读 · 0 评论 -
八大排序之快速排序
为达到数据完整排序的目的,需在一次划分的基础上,返回此时low的位置,然后进行。high位置空出来,因此从前往后找比9大的数字放在High位置,low++high位置空出来,因此从前往后找比9大的数字放在High位置,low++low位置空出来,因此从后往前找比9小的数字放在low位置,high--low位置空出来,从High位置开始查找比9小的数字,high--9>3,从后面High位置开始找比9小的数字,放在low位置。从后往前找比基准小的数字,找到往前挪。从前往后找比基准大的数字,找到往后挪。....原创 2022-07-30 18:00:13 · 706 阅读 · 0 评论 -
八大排序之冒泡排序
思想:依次遍历数组确定下来最大的数字放到最后一位,总共需要遍历n趟,确定下来每一趟里面的最大数均放置到末尾。代码:voidBubbleSort(int* arr, intlen) {boolflag = true;//用于判断是否进入到交换的循环内for(inti = 0; i < len; i++) {for(intj = 0; j < len- i; j++) {if(arr[j] &g.........原创 2021-12-16 20:21:21 · 833 阅读 · 0 评论 -
一元多项式的链式表示-C语言实现
思考:f(x)=4+3x+x^2,如何保存?1.顺序表:只保存系数,指数就是下标,如图所示。有效数据为3,总长度为5(5个格子)问题:如果多项式为h(x)=1+3x^100+4x^200,这样的多项式过于稀疏,存储起来会浪费内存,顺序表长度至少为201,但是只存储了3个数字。因此选用链表2. 链表:每个节点数据保存系数+指数,如图所示。好处:多项式主要是用来进行运算,链表的插入和删除操作相对于顺序表更方便基本操作:多项式的加法、减法、插入、删除、查找、输出。.原创 2022-01-15 17:18:45 · 1417 阅读 · 0 评论 -
【栈】顺序栈知识点-内含基本操作及其说明
函数的设计:bool来判断返回值是否为空,想要把数据带回必须用到指针。判满函数属于内部函数,因为外部函数一般都是动态创建内存,不需要判满。判满条件:数据个数(即当前栈顶位置-栈底0)与容量相等时,栈满。栈空:ps->base==NULL;入栈、出栈、获取栈顶元素、销毁、判空。入栈操作:元素赋值到栈顶,栈顶++栈内总容量为INITSIZE。先判满,如果栈满,扩容。realloc:扩容。原创 2022-01-15 10:21:29 · 1815 阅读 · 0 评论 -
单链表&循环链表&双向链表的不同
循环链表:①判空条件为:p==plist或者p->next==NULL;②判断结尾不同:循环链表的结尾又回到了头(是一个圈圈一样的循环):p==plist;而单链表的结尾时NULL:p==NULL。③循环链表可以从一个结点到达任意节点,而单链表只能顺着链表一直查找下去(因为循环链表可以一直循环下去,而单链表只能走一遍)。双向链表:增加了前驱结点,在涉及前驱结点的头插、尾插、删除操作上有所不同,判空条件仍为p==NULL.①头插与尾插的最后一部插入时,需要把前驱结点连接上,头插法原创 2022-01-14 10:31:35 · 2438 阅读 · 0 评论 -
【链表】双向链表知识点-内含代码基本操作及其说明
说明:循环链表虽然能够实现从任一结点出发沿着链能找到其前驱结点,但时间消耗0(n),双向链表可以实现快速查找到前驱。例如用链表实现逆置时需要很多前移和后移的操作,很麻烦,而引入双向链表,增加对当前结点前驱的存储就很便捷。定义:typedefintElemType;typedefstructDNode{ElemTypedata;//数据structDNode* next;//后继指针structDNode* prio...原创 2022-01-14 10:08:06 · 921 阅读 · 0 评论 -
【链表】循环链表知识点-内含代码基本操作及其说明
认识链表:循环链表就是最后一个结点指向第一个结点(形成了一个环)带头结点的循环链表:尾结点的后继为头结点(不是NULL)结点定义代码如下:typedefintElemType;typedefstructCNode//循环链表节点{ElemTypedata;//数据structCNode* next;//后继指针}CNode, * CList;基本操作:①初始化void InitList(CList plist){ assert(plist...原创 2022-01-11 21:17:38 · 1756 阅读 · 0 评论 -
集合合并(链表实现)
题目说明:实现两个集合的并集AUB,A={1,2,3,4,},B={5,3,1,6};结果:{1,2,3,4,5,6}。并集:相同部分取一次代码解析:1.建立A、B链表,将集合中的数据插入2.合并两个链表,查找B中是否有与A相同元素,如不同插入到A链表中,最终得到的A链表极为最终结果3.使用完后销毁A、B链表代码实现:typedef int ElemType;typedef struct Node{ ElemType data; struct Node*.原创 2022-01-07 11:23:51 · 1904 阅读 · 0 评论 -
【链表】单链表知识总结-内含代码操作及其说明
认识链表:顺序表:逻辑相邻,物理也相邻(例如数组,坐在旁边的一定是舍友)链表:逻辑相邻,物理不一定相邻(坐在旁边的也不一定是舍友)//不能从第一个数一直遍历到最后一个数链表就是线性表的链式表述。因此,链表结点的意义:存放数据+下一个结点的地址①结点定义代码如下:typedefintElemType;typedefstructNode{ElemTypedata;//存放数据structNode* next;// 存放...原创 2022-01-06 18:24:24 · 2598 阅读 · 0 评论