数据结构初阶
文章平均质量分 86
掘根
须知少时凌云志,曾许人间第一流
展开
-
排序3——归并排序,外排序,计数排序
我们可以看一下图来自己先理解一下归并排序归并排序是采用分治法的一个非常典型的应用。其基本思想是:将已有序的子序合并,从而得到完全有序的序列,即先使每个子序有序,再使子序列段间有序。那么如何得到有序的子序列呢?原创 2024-05-12 18:15:07 · 182 阅读 · 2 评论 -
排序2——冒泡排序,快速排序(3种递归方式+3种非递归方式)
然后也是将key的左序列和右序列再次进行这种单趟排序,如此反复操作下去,直到左右序列只有一个数据,或是左右序列不存在时,便停止操作。原创 2024-05-12 13:51:38 · 908 阅读 · 0 评论 -
排序1——直接插入排序,希尔排序,选择排序,堆排序
2.2.2.1. 希尔排序是对直接插入排序的优化。2.2.2.2. 当gap > 1时都是预排序,目的是让数组更接近于有序。当gap == 1时,数组已经接近有序的了,这样就 会很快。这样整体而言,可以达到优化的效果。我们实现后可以进行性能测试的对比。2.2.2.2.2.2.4. 稳定性:不稳定。原创 2024-05-11 12:38:53 · 766 阅读 · 1 评论 -
链式二叉树的基本操作2
接上一篇文章:http://t.csdnimg.cn/oNsQX代码:我们可以画栈展开图来理解一下这个过程,假设我们要在下面这个二叉树里找值为5的结点,它的栈展开图如下。 单值二叉树,所有结点的值都相同的二叉树即为单值二叉树题目:. - 力扣(LeetCode)判断某一棵二叉树是否是单值二叉树的一般步骤如下:若满足以上情况,则是单值二叉树。注:空树也是单值二叉树。3.判断两颗树是否相同题目:. - 力扣(LeetCode)判断两棵二叉树是否相同,也可以将其分解为子问题: 1.比较两棵树的根原创 2024-05-10 19:52:42 · 967 阅读 · 2 评论 -
链式二叉树的基本操作1
既然是链式二叉树,那必须得有自己的结点类型,以下是链式二叉树结点类型的定义,为了避免过多重复的代码,下面的问题都统一使用该结点类型。}BTNode;创建结点。原创 2024-05-09 21:30:29 · 834 阅读 · 4 评论 -
堆的应用2——TOPK问题
比如:专业前10名、世界500强、富豪榜、游戏中前100的活跃玩家等。原创 2024-05-09 12:12:41 · 634 阅读 · 2 评论 -
堆的应用1——堆排序
由于非叶子结点的索引是(n - 1) / 2(向下取整),这里(n - 1 - 1) / 2是为了得到正确的最后一个非叶子结点的索引。每个结点的向下调整时间复杂度为O(logN),但由于每个结点只调整一次,所以整个建堆过程的时间复杂度为O(N)。这里您选择使用向下调整的方法来建堆,这是一个高效的方法,因为向下调整每个非叶子结点只需要O(logN)的时间,并且整个建堆过程的时间复杂度为O(N)。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父结点。原创 2024-04-28 18:04:34 · 1145 阅读 · 24 评论 -
堆的基本操作(c语言实现)
1.7.获取堆的数据个数。原创 2024-05-09 10:09:09 · 686 阅读 · 18 评论 -
堆的介绍,堆的向下调整算法,堆的向上调整算法
数据插入时是插入到数组的末尾,即树形结构的最后一层的最后一个结点,所以插入数据后我们需要运用堆的向上调整算法对堆进行调整,使其在插入数据后仍然保持堆的结构。因此,对于任意结点,其左子结点的下标是其下标的两倍加一,右子结点的下标是其下标的两倍加二,而父结点的下标则是通过将其下标减一后除以二(整数除法)得到。)后,从堆的最后一个元素开始,将其放到堆顶,并通过一系列的交换操作来重新维护堆的性质。使用堆的向下调整算法,最坏的情况下(即一直需要交换结点),需要循环的次数为:h - 1次(h为树的高度)。原创 2024-04-28 13:06:53 · 1019 阅读 · 9 评论 -
树,二叉树的基本概念介绍,二叉树的性质
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。有一个特殊的结点,称为根结点,根节点没有前驱结点除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1原创 2024-04-27 20:43:17 · 995 阅读 · 12 评论 -
栈和队列OJ——括号匹配问题,用队列实现栈,用栈实现队列,设计循环队列
题目来源。原创 2024-04-27 10:12:34 · 700 阅读 · 0 评论 -
队列的实现(c语言实现)
队列(Queue)是一种特殊的线性数据结构,它遵循先进先出(FIFO,First In First Out)的原则。这意味着最早被添加到队列中的元素将是最先被移除的元素。队列的主要操作包括入队(enqueue,在队列的尾部添加元素)和出队(dequeue,从队列的头部移除元素)。队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊。:队列的插入操作叫做入队列,:队列的删除操作叫做出队列,原创 2024-04-25 22:38:00 · 1196 阅读 · 0 评论 -
链栈的基本操作(链表实现)
int data;// 数据域// 指针域。原创 2024-04-27 17:11:19 · 530 阅读 · 0 评论 -
顺序栈的基本操作(动态数组实现)
/栈中存储的元素类型(这里用整型举例)//栈int top;//栈顶//容量,方便增容}Stack;这里定义了一个结构体,并给它起了一个别名Stack。a:这是一个指向STDataType类型的指针,用于存储栈中的元素。它实际上是一个数组,用来存放栈中的各个元素。top:这是一个整数,表示栈顶的位置。在栈中,通常使用top来追踪栈顶元素的位置。当栈为空时,top的值可能是-1或其他表示空栈的值;当栈不为空时,top的值是栈顶元素的索引。capacity:这也是一个整数,表示栈的容量。原创 2024-04-25 21:57:47 · 713 阅读 · 2 评论 -
链表OJ11——随机链表的复制(C++代码实现)
【代码】链表OJ11——随机链表的复制(C++代码实现)原创 2024-04-23 21:58:33 · 400 阅读 · 0 评论 -
链表OJ10——环形链表2(C++代码实现)
声明:我的链表OJ系列是针对无头单向不循环链表的声明:我的链表OJ系列是针对无头单向不循环链表的题目给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。nextpospos-1pos链表。原创 2024-04-23 21:43:04 · 714 阅读 · 0 评论 -
链表OJ9——环形链表1
快指针一次走3步,走4步,...n步行吗?我们可以假设:快指针每走三步,慢指针每次走一步,此时快指针肯定先进环,慢指针后来才进环。原创 2024-04-22 19:56:47 · 1045 阅读 · 0 评论 -
链表OJ8——相交链表
我们假设这两个链表的结点个数之差为count,我们可以让指向较长链表的指针先向后移动count步,然后指向长链表的指针和指向短链表的指针再同时向后移动,这样这两个指针最后会同时走到各自的链表结尾(NULL)。在两个指针同时向后移动的过程中,第一次指向的同一个结点便是这两个相交链表的起始结点。这时返回该结点地址即可。原创 2024-04-22 19:34:53 · 446 阅读 · 0 评论 -
链表OJ7——链表的回文结构(C++代码实现)
声明:我的链表OJ系列是针对无头单向不循环链表的题目声明:我的链表OJ系列是针对无头单向不循环链表的题目。原创 2024-04-21 23:38:44 · 417 阅读 · 0 评论 -
链表OJ6——链表分割(C++代码实现)
一遍传入的链表,将值大于x的结点和值小于x的结点依次尾插到两个链表中,最后再将这两个链表链接起来,并返回第一个结点的位置即可。原创 2024-04-21 21:49:49 · 436 阅读 · 1 评论 -
链表OJ5——合并两个有序链表(C语言实现)
声明:我的链表OJ系列是针对无头单向不循环链表的题目声明:我的链表OJ系列是针对无头单向不循环链表的题目。原创 2024-04-21 21:37:17 · 570 阅读 · 1 评论 -
链表OJ4——删除链表中等于给定值 val 的所有节点(c语言实现)
这样子就完成了特殊情况。原创 2024-04-16 12:04:56 · 566 阅读 · 0 评论 -
链表OJ3——链表中倒数第k个结点
因为从最后一个结点开始,再往后走一步便是NULL;从倒数第二个结点开始,再往后走两步便是NULL;从倒数第k个结点开始,再往后走k步便是NULL。所以我们可以先让快指针(fast)先走k步,然后慢指针(slow)再和快指针一起往后走,这样,当快指针走到NULL时,慢指针指向的结点就是倒数第k个结点。但我们若是为了提高自身的代码能力,上面这种思路是远远不够的,在实际运行时该代码的效率不高,而且这种代码在面试时根本不能“打动”面试官。输入一个单向链表,输出该链表中倒数第k个结点。原创 2024-04-21 23:23:30 · 400 阅读 · 0 评论 -
链表OJ2——链表的中间结点(c语言实现)
所以,我们可以遍历链表,当fast指针遍历到链表末尾时,就立刻返回此时的slow指针即可。需要注意的是:因为fast指针一次是走两步,所以当。原创 2024-04-21 21:13:02 · 387 阅读 · 0 评论 -
链表OJ1——反转链表(c语言实现)
在遍历过程中,每次只改变一个节点的指向,并通过指针的移动来逐步处理链表中的其他节点,最终完成整个链表的反转。这个过程中,关键在于理解链表节点的指向关系是如何改变的,以及如何通过遍历链表来逐步完成这个改变。这样就实现了链表的反转。:当遍历完整个链表后,原链表的头节点就变成了新链表的尾节点,而新链表的头节点则是遍历过程中最后更新的那个节点。:随着遍历的进行,新的头节点会逐渐变为原链表的尾节点。反转链表的基本原理是通过改变链表节点的指向关系,使得原本指向下一个节点的指针现在指向前一个节点,从而实现链表的反转。原创 2024-04-21 20:33:50 · 728 阅读 · 0 评论 -
链表基础4——带头双向循环链表(c语言实现)
/存储的数据类型//数据域//前驱指针//后继指针}ListNode;原创 2024-04-21 11:02:12 · 868 阅读 · 0 评论 -
链表基础3——单链表的逆置(c语言实现)
递归法的好处是代码简洁,但递归深度较大时可能会导致栈溢出。原创 2024-04-15 23:01:14 · 1234 阅读 · 0 评论 -
链表基础2——带头结点单向非循环链表的基本操作(c语言实现)
在“SLTNode”这个缩写中,中间的“T”通常代表“Type”或者“Node”的缩写。在这里,“T”更是为了强调这是一个特定的类型(Type)或者是一个结点(Node)的表示。这些基本操作构成了带头节点单向不循环链表的基本功能,可以根据具体需求进行组合和扩展。需要注意的是,在实际编程中,还需要考虑错误处理、边界条件以及内存管理的安全性等问题。六,在链表尾部插入新结点。七,删除链表的第一个结点。八,删除链表的最后一个结点。,它表示单链表中的结点。三,指定结点的后插操作。四,指定结点的前插操作。原创 2024-04-14 21:44:00 · 1135 阅读 · 0 评论 -
链表基础1——无头结点单向非循环链表的基本操作(c语言实现)
二,尾部插入一个元素。原创 2024-04-14 13:33:09 · 891 阅读 · 0 评论 -
顺序表的基本操作(c语言实现)
顺序表分为静态顺序表和动态顺序表//// 暴力检查//// 温柔的检查SLPopBack 函数用于删除顺序表的最后一个元素。在这个函数中,直接调用了之前定义的 SLErase 函数来完成删除操作。下面是对这个函数的详细分析:这里,ps 是指向顺序表的指针,ps->size-1 是顺序表最后一个元素的索引。通过调用 SLErase 函数,并传入这些参数,可以删除顺序表的最后一个元素。SLErase 函数会首先将位置 pos + 1 及之后的元素向前移动一位,以覆盖掉位置 pos 的元素。原创 2024-04-13 13:26:18 · 1255 阅读 · 2 评论 -
空间复杂度详解
空间复杂度也是一个数学表达式,是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。 注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。它主要关注算法在执行过程中需要开辟的空间,但不原创 2024-04-16 20:25:44 · 829 阅读 · 1 评论 -
时间复杂度详解2——时间复杂度的计算
对于两层循环时间复杂度的计算,我们完全可以将这个循环视作一个单层循环,然后它的循环体是另一个循环。这样子计算起时间复杂度就很简单了实际上无论多少层循环,我们只需一层一层分开来计算就行了,最后只需将最内层的语句的执行次数全加起来就好了例一:要计算这个嵌套循环的时间复杂度,我们首先要分析每个循环的执行次数。外层循环 从 到 ,因此会执行 次。对于每一个 的值,内层循环 的执行次数从 到 。具体来说:因此,内层循环的总执行次数是 ,这是一个等差数列的和,其和为 (\frac{(n+1)(n+2)原创 2024-04-12 21:43:56 · 937 阅读 · 4 评论 -
时间复杂度详解1——定义和简单计算
我们的计算机前辈们,为了对算法的评判更科学,研究出了一种叫做事前分析估算的方法。事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算。(1)条当然是算法好坏的根本,第(2)条要由软件来支持,第(4)条要看硬件性能。也就是说,抛开这些与计算机硬件、软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。所谓问题输入规模是指输入量的多少.我们来看看今天刚上课时举的例子;两种求和的算法;第一种算法(注意for循环最后还要多执行一次条件判断)第二种算法显然,第一种算法,执行了1原创 2024-04-12 18:43:48 · 1176 阅读 · 0 评论