数据结构初阶
文章平均质量分 81
数据结构初阶
哎呀怎么回事^_^
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
数据结构-排序扩展
三路划分算法解析:,三路划分的核⼼思想有点类似hoare的左右指针和lomuto的前后指针的结合。核⼼思想是把数组中的数据分为三段【⽐key⼩的值】 【跟key相等的值】【⽐key⼤的值】,所以叫做三路划分算法。结合下图,理解⼀下实现思想:1.key默认取left位置的值。2.left指向区间最左边,right指向区间最后边,cur指向left+1位置。3.cur遇到⽐key⼩的值后跟left位置交换,换到左边,left++,cur++。4.原创 2025-05-12 01:00:00 · 1591 阅读 · 0 评论 -
数据结构-排序
因为是让end先走的,end是要找小于基准值的位置,这里分析begin和end相遇的几种情况:情况一,end找不到比基准值小的,那么最后相遇的位置就是基准值的位置,跳出循环,自己和自己交换,递归右边的部分;这里取最左边地的数据,那么从后面开始找,找到比基准值小的就把这个值放在坑的位置,那么这个比基准值小的数据的位置又形成了一个坑,从前面开始找找到比基准值大的值就把这个值放在上次的坑处,最后end和begin相遇,相遇得到位置也是一个坑,最后把基准值放在这个坑处;这样也能把大的值放到后面,小的放在前面;原创 2024-12-04 15:05:16 · 1470 阅读 · 0 评论 -
LeetCode-二叉树
反之,申请一个二叉树节点,再让此时访问的数组里面的字符赋值给这个节点val,同时让这个节点的左子树和右子树同样进行构建二叉树的操作,形成递归,最后访问的符号是‘#’,返回NULL,这时构建完毕,递归返回;定义一个新的函数,依次拿根节点的值和左右节点的值去和data值比较,若是不同则返回false,反之则继续递归比较,当root为空的时候,就说明比较完了,比较完还没有不一样的就返回true;第二层之后比较的就是左子树和右子树的根节点,所以递归传参的时候传的是根节点的左子树根节点和右子树根节点;原创 2024-08-02 17:30:13 · 873 阅读 · 0 评论 -
二叉树实现(1)
为了方便理解,首先从二叉树的前、中、后三种遍历说起;首先,手动创建一个简单的二叉树作为测试用例;}BTNode;exit(1);那么此时该二叉树就是这样的:叶子节点(3、5、6所在的节点)的左右子树都是NULL;原创 2024-07-31 14:13:56 · 919 阅读 · 0 评论 -
二叉树实现(2)
首先当遍历到第一个为空的节点就跳出循环,它所在的上一层的节点都已经遍历完,那么它上一层所有节点的左右节点都已经存放到队列里面了(删除队列里面的根节点和存放这个根节点的左右节点的动作是同一次循环进行的),那么这些左右节点一定有放到这个空节点后面的节点吗,若是空节点后面都是空节点,那么就说明最后一层的节点是连续摆放的了,那么二叉树就是完全二叉树,和假设不是二叉树的情况不符合;下一次循环还是先打印队列对头的节点,再删除它,每次都要判断删除掉的节点的左右指针指向的节点是不是空,不是空就插入队列;原创 2024-07-31 16:22:44 · 369 阅读 · 0 评论 -
堆的相关算法效率计算
首先我们知道堆是完全二叉树,考虑情况最坏也就是堆的节点个数最多的情况:完全二叉树的最后一层节点是满的(即满二叉树),这里展示的图片是四层,现在假设有一颗满二叉树,它的总高度是H,也就是H层;假设总共的节点有N个;每一层的节点个数是 2^(h-1) (h是每一层的高度):例如第一层就是 2^0 即一个节点后面依次类推;那么N=2^0+2^1+2^2+2^3+……2^(h-2)+2^(h-1),通过等比数列计算公式可知,N=2^H -1;原创 2024-07-25 18:16:50 · 1158 阅读 · 0 评论 -
堆的基本实现
在提出堆的概念之前,首先要了解二叉树的基本概念一颗二叉树是节点的有限集合,该集合:1、或者为空;2、或者由一个根节点加上两颗分别称为左子树和右子树的两颗子树构成;堆就是一颗完全二叉树;堆有两种:小堆和大堆堆在内存上的存储是数组形式的(物理结构);我们认为想象成链式结构(逻辑结构)通过数组结构去实际存储,有这样的规律:每个父节点的下标乘以2加1就是左孩子节点,加2就是右孩子节点;无论是左孩子还是右孩子,其下标减去1再 /2 就是父节点的下标,这就是通过数组存储堆(完全二叉树)的优点。原创 2024-07-25 14:42:05 · 642 阅读 · 1 评论 -
栈和队列的相关题目
int* a;int head;int tail;int k;//后续会用到队列长度int size;obj->k = k;return obj;//走到这里说明还没有满,size小于4return -1;return -1;free(obj);obj = NULL;/***/此处为开辟多的空间,为了避免假溢出的问题定义一个size记录队列里面元素的个数,当size==k的时候就说明满了,当size==0的时候说明为空;原创 2024-07-20 13:58:37 · 1208 阅读 · 0 评论 -
队列的实现
在前面实现单链表或者是双向链表的时候,都是先在头文件里面定义好链表节点指针,这个操作在队列里面也是同样的,QNode结构体指针里面同样包含next指针和节点数据val;而下面的Queue结构体存在的原因是这样的:首先队列的特点就是先进先出,出涉及到头节点,进涉及到尾节点,此时定义好一个结构体Queue让传参更为方便,只需要传Queue结构体指针就可以实现队列的基本操作了,并且最重要的一点是每次进行尾插的时候不需要找尾,我们知道单链表找尾需要遍历链表,效率较低,所以定义好一个队列结构体是优大于劣的;原创 2024-07-18 20:58:59 · 783 阅读 · 0 评论 -
基于数组的栈的实现
栈是一种特殊的线性表,它只允许在一端进行数据的插入和删除操作,这个进行插入和删除的一端被称为栈顶,另一端称为栈底;栈中的元素遵守后进先出的原则LIFPO(last in first out)压栈:栈的插入操作叫做压栈\入栈\进栈,入数据在栈顶;出栈:栈的删除操作叫做出栈,出数据在栈顶。原创 2024-07-18 11:54:49 · 305 阅读 · 0 评论 -
顺序表和链表区别
顺序表的劣势是容量不够的时候需要申请空间,而申请空间用到realloc函数,这个函数拷贝数据,释放就空间,开辟新空间,这样就相对降低了程序的效率;链表只需要按需申请节点空间,相对提高了空间的利用率。链表却不一样,链表的数据,即每个节点都是malloc开辟的,它们在内存上的存储不一定连续,那么在把一个数据载入缓存的时候,已知这个数据附近的数据也要载入,可是链表的数据内存空间不连续,载入时会把一个数据附近不需要的内容载入缓存区,这些不需要的会把缓存区里面有用的数据挤出去,这样就降低了缓存利用率。原创 2024-07-17 19:44:51 · 389 阅读 · 0 评论 -
LeetCode-随机链表的复制
解释为什么要这样:假设现在要实现这个链表中一个拷贝节点的random指向,已知其他拷贝对象的next指向的就是拷贝节点;只需要让这个拷贝节点的random指向它自己拷贝对象的random的next,这个被指向的拷贝节点就是原链表中这个要实现random指向的拷贝节点的拷贝对象的的random的next指向的拷贝节点;先一个一个节点的拷贝,并且把拷贝的节点放在拷贝对象的后面,再让拷贝节点的next指向原链表拷贝对象的下一个节点,这样做的目的是实现拷贝节点的插入,即拷贝好的节点都放在原链表两个节点之间;原创 2024-07-17 18:54:18 · 361 阅读 · 0 评论 -
LeetCode-环形链表、环形链表 II
判断是否有环,使用快慢指针,开始时都指向头节点,快指针每次走两部,慢指针每次走一步,如果在走的过程中,慢指针和快指针相同(也就是快指针和慢指针指向的节点的同)那么就说明这个链表是带环链表;若是这个链表代换,那么快慢指针一定不会走向NULL;只会在这个链表里面循环走下去,并且当循环条件允许时都会进环;原创 2024-07-16 12:18:04 · 1778 阅读 · 0 评论 -
算法的时间复杂度和空间复杂度-概念
在计算机科学中,时间复杂度是一个函数,它定量地描述了一个算法运行所耗费的时间;从理论上来说,这是不能算出来的,只有把这个算法放在编译器里面运行去比较才能得知这个算法的运行时间长短;所以为了方便衡量,才有了时间复杂度的分析方式:一个算法的运行时间与语句的执行次数成正比,算法中基本操作的执行次数,成为算法的时间复杂度。那么如何来确定算法的语句执行次数呢?// 请计算一下Func1中++count语句总共执行了多少次?i < N;++ i)j < N;k < 2 * N;原创 2024-07-14 12:59:30 · 1793 阅读 · 0 评论 -
LeetCode-返回链表倒数第K个节点、链表的回文结构,相交链表
本体思路参展寻找中间节点的方法,寻找中间节点是定义快慢指针,快指针每次走两步,慢指针每次走一步,当快指针为空或者快指针的下一个节点是空时,此时的慢指针指向的节点就是中间节点;并且此时的快指针和慢指针之间的节点个数就是整个链表的一半;据此同理,可以定义快慢指针,使得快指针走到尾的时候,与慢指针之间的差距恰好是k个节点,那么此时的慢指针就是题中要求的节点;原创 2024-07-15 14:38:26 · 737 阅读 · 0 评论 -
算法的时间复杂度和空间复杂度-例题
本题要求的时间复杂度是O(n) ,所以我们不能用循环嵌套;原创 2024-07-14 20:03:57 · 601 阅读 · 0 评论 -
双向带头循环链表
何为双向:此链表每一个节点的指针域由两部分组成,一个指针指向下一个节点,另一个指针指向上一个节点,并且两头的节点也是如此,头节点的下一个节点是尾节点,尾节点的上一个节点是头节点;何为带头:此处的头节点是一个 哨兵位,在链表定义时就要手动设置,此节点只是起到头的作用,并不是真正的节点;在双向带头循环链表为空时,链表中只有一个头节点,当链表中连头节点都不存在时,此链表不能被称作一个有效链表;原创 2024-07-11 15:45:18 · 875 阅读 · 0 评论 -
LeetCode(2)-反转链表、删除链表中等于val的节点、返回链表中的中间节点
目的是让n1成为新的头节点,让n2的next指向n1,让n1=n2,n3=n3->next,那么循环一次之后的链表是NULL<-1 2->3->NULL(此处->表示箭头),第一次循环之后n1数据域是1,n2数据域是2,n3的数据域是3;当链表为偶数个时当快指针为NULL时返回慢指针;快慢指针,定义两个指针,利用循环,慢指针每次走一步,快指针每次走两步,最后快指针的next指针为NULL或者是快指针本身为NULL时,结束循环 ,返回慢指针;n1数据域是3,n2是NULL,n3是NULL,循环结束。原创 2024-07-09 20:04:11 · 452 阅读 · 0 评论 -
LeetCode(2)合并链表、环形链表的约瑟夫问题、链表分割
则第二次循环进入else语句:开始删除数据,但是为了找到之后的链表节点,先让prev的next指针指向pcur的next指向的节点,再删除pcur(此时是2,符合题意,报数为2的删除)再让pcur为prev->next。此时循环进入if语句,count变为2(正常报数),prev的val为3,pcur的val为4;再一次循环进入else语句,开始删除数据让prev的next指向pcur的next(也就是val为5的节点),再删除pcur(val为4的节点),让pcur为prev的next;原创 2024-07-10 20:34:42 · 569 阅读 · 0 评论 -
单链表详解(2)
查找节点我们是通过看数据域来查找的,查找节点函数的返回值类型是SLTNode* 因为不涉及到链表的修改,我们只需要传值;同样地,首=首先要断言看链表是否为空;为了方便遍历链表,我们定义一个节点pcur,在循环中没经历一个节点时,就拿这个节点地数据域的值和传入的数据进行比较,直到最后一个几点,如果某个节点的数据域的值和传入的值相同,就返回这个节点,若是遍历完链表还是找不到,说明这个链表没有要查找的节点,那么就返回NULL。原创 2024-07-09 12:48:08 · 907 阅读 · 0 评论 -
单链表详解(1)
链表是线性表的一种,链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑结构是通过链表中的指针链接次序实现的单链表的结构:单链表就像是一节一节车厢构成的火车,每一节都称为一个节点,节点里面有两部分:数据域和指针域;指针域指向的是下一个节点的地址,依次类推;int data;通过next指针我们可以从头一直访问到最后一个节点。return 0;原创 2024-07-09 11:39:54 · 1563 阅读 · 0 评论 -
移除元素&&合并两个有序数组-LeetCode
题目描述:采用双指针的方法;原创 2024-07-08 12:30:33 · 321 阅读 · 0 评论 -
基于顺序表的通讯录实现
基于已经学过的顺序表,可以实现一个简单的通讯录。原创 2024-07-06 21:34:46 · 661 阅读 · 0 评论 -
顺序表(1) 基础(详解+学习历程)
顺序表是数据结构的一种。数据结构是计算机存储、组织数据的一种方式。数据结构中一种称为线性结构的逻辑结构主要是对线性表的学习,线性表包含顺序表。线性表是对一类事物的集合的统称;线性表不一定有物理结构,但是一定有逻辑结构;顺序表含有物理结构,也含有逻辑结构;含有物理结构就是那一类事物实际上是按照一种特定的有序的方式排列,而含有逻辑结构是人为可以想象成这类事物是按照一定顺序排列的。举例(一类事物):有几种水果,它们可以被称为线性表。为什么呢?原创 2024-07-05 13:33:22 · 884 阅读 · 0 评论
分享