- 博客(23)
- 收藏
- 关注
原创 十六、快速排序
分治思想,通过选择一个基准数,将数组分为两个部分(比基准数小的元素放在基准的左边,比基准数大的元素放在基准数的右边),一部分的元素都比基准数小,另一部分元素都比基准数大,然后递归调用快速排序,对左右子数组分别进行快速排序。原地排序,不需要额外的空间。最优情况:O(nlogn)最坏情况:O(n^2)
2025-02-28 11:46:11
150
原创 十五、 串
串的拼接是将两个串拼接在一起,一般是申请一块新的内存,新的内存的大小是两个需要拼接的字符串的长度加一,然后将第一个串的字符赋值到新的内存中,再将第二个串的字符赋值到新的内存上,最后在结尾加上一个‘\0’。字符串的长度指字符串中包含的字符的个数。串,也叫字符串,是由一系列字符组成的数据结构,用于表示文本或字符序列。在实际内存中存储的时候,字符串最后还会有'\0'的字符,代表串的结尾。一般可以通过遍历的方式实现字符串的拷贝,也要拷贝'\0'。串的索引与顺序表的索引一样(串本身也是一个顺序表)。
2025-02-02 00:50:31
162
原创 十四、图
图是有定点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V , E), 其中G表示一个图,V 是图G中顶点的集合, E是图中边的集合。(线性表中的数据元素称为元素, 树中将数据元素称为结点,图中数据元素称为顶点)
2024-12-23 15:37:32
391
原创 十三、二叉搜索树
二叉搜索树的 查找 、插入 、和 删除 完全取决于二叉搜索树的形状,若接近完全二叉树,则为O(log n),如果是斜树,则这三个操作近似成线性表,则为O(n)。
2024-12-23 14:57:22
589
原创 十、 队列
队列是仅限在表尾进行插入,表头进行删除的线性表,遵循先进先出的原则。通常用于实现 排队系统,任务调度,消息传递等。我们可以用顺序表或链表来实现队列。利用队首指针获取队首元素并返回,不会改变队列本身数据。队列的插入操作,将数据元素从队尾进行插入的过程。1、将元素添加到队列尾部,更新队尾指针或索引。1、删除队首元素,更新队首指针或者索引。返回队首指针(索引)指向的元素的值。队首元素的删除操作。2、队列的大小减一。
2024-12-09 22:17:20
346
原创 九 、 栈
可以比作一堆盘子,只能访问顶部的盘子,而添加和删除只能在顶部进行。直接将栈的顶部元素删除即可。这个操作类似于将叠盘子的顶部的盘子拿走的过程。栈常用于实现函数调用、递归、表达式求值等操作,一般用 顺序表 或者 链表 来实现栈。栈元素的插入操作叫做入栈,也可以称为进栈、压栈。返回栈顶元素的值,不管是链表还是顺序表,时间复杂度为O(1)。1、将元素压入栈中,并将栈顶指针或索引指向新的栈顶元素。1、将栈顶元素删除,并将栈顶指针或索引指向新的栈顶元素。2、栈的大小增加了1,顶部元素为刚刚入栈的元素。
2024-11-18 14:59:17
315
原创 八、单向链表
链表由一个个结点组成,每个结点之间通过链接关系串联起来,每个结点都有一个后继结点,最后一个结点的后继结点为空节点。3、如果插入位置是0,则直接把生成的结点的后继结点设置为当前的链表头结点,并且把生成的结点设置为新的链表头。3、如果删除位置不是首结点,则遍历到要删除的位置的前一个结点,并把前一个结点的后继结点设置为它后继的后继。1、遍历一个链表,对链表中每个元素和指定元素进行比较,如果相等,则返回当前遍历到的结点。4、如果插入位置不是0,则遍历插入位置的前一个位置,把生成的结点插入进来。
2024-11-11 15:37:36
656
原创 七、顺序表
在顺序表中查找指定元素是否存在,如果存在,则返回该元素的索引。给定一个索引和一个元素,将这个元素插入到对应索引位置上,这个位置以后的所有元素都要向后移动一个位置。给定一个索引,将这个索引上的元素删除,并且把这个索引位置以后的所有元素都向前移动一个位置。1、遍历整个顺序表,对顺序表中的每个元素,和指定元素进行比较,如果相等,则返回当前的索引。3、如果不是最后一个元素,则将删除位置之后的元素向前移动,覆盖要删除的元素。2、如果顺序表已满,则需要扩容顺序表,一般是把原有顺序表的容量进行倍增。
2024-11-04 22:57:27
286
原创 六、快速排序
快速排序的空间复杂度是O(logn),因为其在递归调用中需要使用栈来存储·中间结果,这意味着在排序过程中,最多需要O(logn)的额外空间来保存递归调用的栈帧。分开排序,首先,通过选择一个基准元素,将数组分为两部分,一部分比基准小,另一部分元素比基准大,然后再递归调用对这两部分再进行快速排序,最终得到有序数组。2、分割元素,将比基准元素小的元素放在基准元素的左边,将比基准元素大的放在基准元素的右边。最坏情况:当每次选择的基准元素是最大或最小元素时,快速排序的时间复杂度是O(n^2)。
2024-11-04 17:34:30
367
原创 五、归并排序
归并排序对应的数据结构是一棵二叉树,对于两个大小为n1,n2的排序数组A和B,我们可以在O(n)时间内进行排序,归并排序调用的次数就是二叉树的高度log2n, 所以归并排序的时间复杂度为O(nlog2n)。实现用一个和给定元素个数一样大的数组,作为函数传进去,所有 辅助数组能干的事情,都可以在这个传参进去的数组上进行操作,这样就免去了内存的频繁的申请和释放。整个算法的执行过程用mergeSort(a[ ], l, r)描述,代表当前待排序数组a,左区间下标l,右区间下标r,分以下步骤。
2024-11-03 16:38:59
1408
原创 c语言中用new创建数组
• 例如,要在堆上创建一个int类型的变量,可以这样写:int* ptr = new int;例如int* arr = new int[5];,这就在堆上创建了一个包含5个int元素的数组。当你使用new在堆上分配内存后,一定要记得在适当的时候释放内存。),对于用new[]分配的数组,使用delete[](如delete[] arr;• 如果想在分配内存的同时初始化变量,可以这样写:int* ptr = new int(10);• 不过要注意,使用new分配的数组,需要用delete[]来释放内存。
2024-11-01 22:45:26
601
原创 memset的使用
在C++中,memset用于将一段内存空间设置为指定的值。它在头文件<cstring>中,函数原型是void *memset(void *ptr, int value, size_t num);,主要用于对数组(如字符数组)进行初始化。memset用于将一段内存空间设置为指定的值。一般用法是memset(起始地址,要设置的值,字节数)。比如memset(arr,0,sizeof(arr))能将数组arr的所有元素初始化为0。
2024-11-01 11:01:09
153
原创 四、计数排序
第四个循环,是嵌套在第三个循环内的,最多走O(n),虽然是嵌套,但是它和第三个循环是相加关系,并非相乘关系。计数排序的算法核心是创建一个计数数组,用于记录每个元素的出现次数。第二个循环枚举所有数字,执行 哈希 和 计数 操作,时间复杂度O(n)。1、初始化一个长度为需排序数组的最大元素加1的计数器数组,所有元素初始化为0。4、遍历计数器数组,按照数组中元素个数放回到原数组中。第一个循环用于初始化计数器数组,时间复杂度为O(k)。2、第三个循环中,当排序元素达到n个时,可以提前结束。
2024-10-31 23:31:19
838
原创 三、插入排序
执行时,由于在移动过程中,只有在移动变量时,需要将变量存入临时变量x,没采用额空间,因此,空间复杂度为O(1)。3、如果该元素小于已排序部分的最后一个元素,就将其插入到已排序部分的适当位置。可以利用二分查找,但是优化的也是常数时间,最大的时间复杂度是不变的。外循环正好运行 n-1 次,但内循环运行变得越来越短。2、取出下一个元素,与已排序部分的元素进行比较。1、从第一个元素开始,并将其视为已排序部分。2、稳定性好不会改变相等元素的相对顺序。重复步骤二和三,直到整个数组都被排序。1、简单,易于实现。
2024-10-30 23:07:11
192
原创 二、冒泡排序
算法在执行过程中只有在交换变量时才采用了临时变量的方式,没有采用任何额外的空间,因此,空间复杂度为O(1)。外层循环是可以提前终止的,在首轮比较过程中没有发生交换,可以直接跳出循环,算法提前终止。2、对于大型数组,冒泡1排序时间复杂度较高,速度慢。为0~n-1的等差数列求和,为n(n-1)/2。2、对每一个元素,预期后一个元素进行比较。1、遍历数组的第一个元素到最后一个元素。因此,总的时间复杂度为O(n^2)。1、效率低,需要进行多次比较和交换。3、如果顺序错误,就将他们交换。
2024-10-29 22:59:04
599
原创 一、选择排序
可以用 线段树 来优化,内层循环时间复杂度可以优化成O(log2n),总的时间复杂度变成O(nlog2n)2、不稳定,排序过程中可能会改变相同元素的相对顺序。1、 用第一个元素遍历数组,在未排序的序列中找到。1、时间复杂度较高,处理大规模数据时效率低。小(大)元素,然后放到已排序序列的末尾。3、重复第二步,直到所有元素均排序完毕。2、原地排序,不需要额外的存储空间。2、再从剩余未排序的元素中继续寻找。小(大)元素,存放到起始位置。原地排序,空间复杂度为O(1)3、适用于小型数组。
2024-10-28 21:49:05
611
原创 c语言中,用异或交换数字
异或运算的规则是:相同为 0,不同为 1。一个数的二进制位与 0 的对应二进制位进行异或操作时,因为 0 的每一位都是 0,所以该数的每一位都保持不变,结果就是这个数本身。(同上,这个式子可以写为a=a^b^b,因为经过上个步骤,a的值已经赋值给b了,所以可以继续化简为a=a^b^a=a^a^b=0^b=b)(等号右边的a还是第一个式子的a等于a^b)(此时,a=a^b,这个式子可以写成b=a^b^b=a^0=a)在 C++中,任何数与 0 异或的结果都是这个数本身。这样,完成了交换数值的操作。
2024-10-27 17:25:22
333
原创 vector
在c++中vector是一个柔性数组,在C++中,vector是一个动态数组模板类,用于存储同类型的元素序列,可以方便地进行插入、删除、访问等操作。要使用vector需包含头文件。
2024-10-26 14:52:49
126
原创 c语言中的memcpy函数
在c语言中,memcpy函数用于从源地址复制一定长度内容到目标地址,使用时需要包含<string.h>头文件,它的函数原型是void *memcpy(void *dest, const void *src, size_t n);如果要从数组a复制k个元素到数组b,可以使用memcpy函数:memcpy(b, a, sizeof (int)*k)。当a和b都是浮点型时,可以把int改为double,如果要把数组a全部复制到数组b中,可以简写为:memcpy(b, a, sizeof (a))。
2024-10-25 20:46:27
785
原创 qsort函数(来源于豆包)
在这个例子中,compare函数用于比较两个整数的大小,qsort函数根据这个比较函数对整数数组进行排序。4. compar:指向比较函数的指针,该函数用于确定两个元素的顺序。qsort函数是 C 语言标准库中的快速排序函数。3. size:每个元素的大小(以字节为单位)。1. base:指向要排序的数组的起始地址。2. nmemb:数组中的元素个数。• 小于 0:表示 a 小于 b。• 等于 0:表示 a 等于 b。• 大于 0:表示 a 大于 b。
2024-09-12 12:56:13
321
原创 malloc
1. malloc分配的内存是未初始化的,其内容是不确定的。如果需要特定的初始值,可以在分配后手动初始化。3. 在进行指针运算或访问分配的内存时,要确保不超出分配的内存范围,否则可能导致未定义行为。2. 确保在使用完内存后及时释放,否则可能导致内存泄漏,尤其是在长时间运行的程序中。int *ptr = (int *)malloc(sizeof(int)*(元素个数));3.不再需要内存时,用free释放内存。
2024-09-12 11:42:35
528
1
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅