数据结构
文章平均质量分 55
编程小程
这个作者很懒,什么都没留下…
展开
-
八大排序之快速排序以及优化(5)
文章目录快速排序快速排序递归形式算法步骤代码实现快速排序非递归形式算法优化快速排序快速排序是一个在大多数情况下排序性能最好的一个算法,通常情况下,数据规模越大,数据越乱,快速排序的性能越好。下面将说明快速排序具体实现进行说明,并对其进行优化。快速排序递归形式算法步骤代码实现在这里插入代码片快速排序非递归形式算法优化...原创 2022-04-24 10:53:09 · 296 阅读 · 0 评论 -
字符串匹配(2)----KMP算法
文章目录字符串匹配-KMP算法算法流程字符串匹配-KMP算法我们将介绍KMP算法进行字符串匹配,Knuth-Morris-Oratt字符串查找算法,主要用于在一个文本串(主串)查找一个模式串(子串)的出现位置。算法流程假设...原创 2022-04-04 20:45:56 · 364 阅读 · 0 评论 -
字符串匹配(1)--- BF算法
字符串匹配BF算法如果i和j指向的字符相同,则i++,j++如果i和j指向的字符不相同,则i=i-j+1,j=0;退出条件: 如果i或者j走出自身范围(越界)退出之后,我们需要判断到低子串在主串中出现与否代码实现int BF_search(const char *str,const char *sub,int pos){ assert(str != NULL && sub != NULL && pos >= 0 && pos <原创 2022-04-02 10:51:50 · 749 阅读 · 0 评论 -
八大排序之二路归并排序(4)
文章目录归并排序排序规则代码实现测试算法复杂度分析归并排序首先将所有数据默认每个数据单独分成一个组,接下来两两合并,当所有数据在同一个组内,则排序完成。排序规则将所有数据单独给每个数每个组(每个数据单独看,就是有序的)然后将数据进行两两合并成一组,对每一组数据进行排序然后继续把数据两两合并排序,直到只有一组数据原始数据: 84 9 18 19 48 12 90 &原创 2022-03-29 21:19:16 · 290 阅读 · 0 评论 -
八大排序之选择排序和基数排序(桶排序) ---(3)
主要介绍了选择排序和基数排序的算法思想,排序规则,并用C语言将其实现,最后再分析了其算法复杂度原创 2022-03-26 10:02:12 · 1865 阅读 · 0 评论 -
C语言实现飞机订票系统
为了增加对数据结构中链表知识的理解和对实际问题的应用,文中将用C语言实现飞机订票系统,主要实现了机票信息的添加、查找、显示、修改和订票、退票功能,其中用链表来存储数据,程序结束时,可以把数据保存到文件中。原创 2022-03-24 11:24:29 · 12160 阅读 · 14 评论 -
八大排序之堆排序和冒泡排序(2)
主要介绍了关于堆排序算法的算法思想和算法步骤,并且用c语言将其实现,分析其算法复杂度原创 2022-03-22 12:09:04 · 1102 阅读 · 0 评论 -
八大排序之直接插入排序和希尔排序(1)
介绍了直接插入排序和希尔排序的思想和排序规则,并用c语言对其进行实现,进行测试,最后分析了其算法复杂度。原创 2022-03-19 09:30:25 · 682 阅读 · 0 评论 -
为什么要构建哈希表?
为什么要构建哈希表?现在有一组数据,我们想查找一个值(x)是否在这组数据中,通常来说,我们需要把这组数据遍历一遍,来看看有没有x这个值。这时,我们发现这样查找数据要花费的时间复杂度为O(n),链表、顺序表都是如此。为了降低查找数据的时间复杂度,那我们就不能去遍历所有的数据来查找,我们需要找到新的方法来查找数据,这时我们就引入了哈希表。哈希哈希就是根据设定好的哈希函数和处理发生哈希冲突的解决方法,哈希是一种存储方法,也是一种查找方法,算法中只要用到这种哈希思想,就可以叫做哈希算法(hash)哈希函原创 2022-03-15 13:48:27 · 1033 阅读 · 0 评论 -
两个栈实现一个队列的功能
用两个栈实现一个队列,栈采取之前实现的顺序栈,具体实现的规则如下:首先定义两个栈s1,s2。入队规则: 入队只向s1入队出队规则:看s2有没有值,有的话,直接出即可。如果s2没有值,将s1里面的值全部颠倒放入s2中,然后再从s2出队两个栈实现一个队列的结构体定义://用两个栈模拟实现的结构体typedef struct Two_stack_queue{ Stack s1; Stack s2;}Two_stack_queue ,*PTwo_stack_queue;原创 2022-03-08 15:44:51 · 689 阅读 · 0 评论 -
链表----队列
队列的链表实现形式,在链表中,入队操作相当于链表中的尾插操作,出队操作相当于链表当中的头删操作。为了使得在链表中队列的出队入队操作的时间复杂度也都是O(1)因此我们需要第一时间可以找到链表的头和链表的尾。为此,我们需要在头结点中定义两个指针域分别指向队列的头节点的地址和队列的尾节点的地址。具体结构如下图所示:头节点的结构体成员里面有两个指针域,而有效数据节点的结构体成员只有一个指针域,因此为了避免空间浪费,我们对头节点和有效数据节点分别单独设计结构体:typedef int ELEM_TY原创 2022-03-07 22:07:01 · 2375 阅读 · 0 评论 -
链表----栈
链栈: 单链表的基础上实现即可用单链表的头插和头删代替表尾进行插入和删除 push(头插) pop(头删)入栈操作(相当于单链表的头插函数)bool Push(PLStack ps,ELEM_TYPE val){ assert(ps != NULL); if (ps == NULL) { return false; } struct LStack* pnewnode = (struct LStack*)malloc(1 * sizeof(ELEM_TYP...原创 2022-03-04 21:27:36 · 1476 阅读 · 0 评论 -
寻找单链表倒数第K个节点
单链表只能从前往后跑,不能从后往前,因此我们申请两个指针p,q,让q指针先向前走K步,然后两个指针同时向后跑,当q指针跑到NULL时,q指针所处的位置就是我们要寻找的倒数第K个节点//找到单链表倒数第K个节点struct Node* Get_K_Node(PNode plist, int K){ assert(plist != NULL); assert(K >= 1 && K <= Get_length(plist)); PNode p = plist; .原创 2022-03-03 09:00:00 · 347 阅读 · 0 评论 -
判断单链表是否存在回文
回文即就是 “123454321”,“abcba"满足这样的数据链表,需要两个指针,一个指向头,一个指向尾,一个向后走,一个向前走,判断数据是否相等。但是单链表无法从后节点指向前节点,因此将单链表中数据拷贝到数组中进行判断。代码实现如下://判断单链表是否回文bool IsPail(PNode plist){ //需要两个指针,一个指向头,一个指向尾,一个向后走,一个向前走,判断数据是否相等 //单链表无法从后节点指向前节点,因此将单链表中数据拷贝到数组中进行判断 int len = G原创 2022-03-01 09:00:00 · 327 阅读 · 0 评论 -
删除链表任意一个节点(不包括尾结点)
//删除任意一个节点(这个节点不能是尾结点)(狸猫换太子)bool Del_Node(struct Node* p){ assert(p != NULL);//确保p存在 assert(p->next != NULL); //确保狸猫的存在(p不能是尾结点) PNode q = p->next; p->data = q->data; p->next = q->next; free(q); return true;}...原创 2022-03-02 09:00:00 · 763 阅读 · 0 评论 -
顺序表----队列
队列:和栈一样,也是受到限制的线性表,与栈不同的地方在于,它遵循着先进先出(FIFO)的规则一端进行入队,一端进行出队,我们将入队的一端称作队尾(允许插入的一端),另一端称作队头(允许删除的一端),示意图如下通过顺序表实现的队列,一般我们将其称为循环队列,原因如下:因为我们构建的队列,当要出队的时候,如上图,从队头a1出队,那么后面所有数据都需要向前移动一步,则队列的出队时间复杂度是O(n)为了使队列和栈一样,出队和入队的时间复杂度都为O(1),我们把队列想象成环形(不是真实存在的)原创 2022-02-28 10:56:56 · 609 阅读 · 0 评论 -
判断两个单链表是否相交,若相交并找出相交的第一个点
链表的正确相交情况如下:判断两个链表是否相交//确定两个单链表是否相交 (用两个指针跑到两个单链表的尾结点,然后判断是否是同一个尾结点)bool Intersect(PNode plist1, PNode plist2){ //assert PNode p1 = plist1; PNode p2 = plist2; for(p1; p1->next!=NULL; p1=p1->next); //此时for循环结束 p1在plist1这个单链表的尾结点上 .原创 2022-02-19 09:00:00 · 311 阅读 · 0 评论 -
单链表的逆置
用两种方法实现对单链表的逆置操作1. 用无线头插的方法实现//逆置1 无线头插bool Reverse1(PNode plist){ assert(plist != NULL); PNode p = plist->next; PNode q ; plist->next = NULL; while (p!=NULL) { q = p->next; p->next = plist->next; plist->next = p;原创 2022-02-18 23:03:23 · 184 阅读 · 0 评论 -
顺序表---栈
栈 :只能在表尾进行插入(入栈)和删除(出栈)的数据结构(受到限制的线性表)表尾比较特殊,我们一般把这个表尾叫做栈顶,另一端栈底,没有数据节点,则叫做空栈。特点:后进先出 (LIFO),先进后出顺序栈结构体设计:struct Stack{ 第一个数据成员:base(指针类型,接收malloc从堆里...原创 2022-02-16 13:23:18 · 833 阅读 · 0 评论 -
线性表---循环链表
循环链表:循环链表的特点是可以通过尾结点的指向找到头结点的地址;结构体设计与单链表相同:typedef int ELEM_TYPE;typedef struct Clist{ ELEM_TYPE data; //数据域 struct Clist* next; //指针域 } Clist, * PClist;主要功能实现如下:1.初始化操作循环列表初始化操作中需要将首节点的next域指向它本身的地址void Init_clist(s原创 2022-02-11 23:21:04 · 146 阅读 · 0 评论 -
线性表--双向链表
双向链表:相比于单链表,双向链表有两个指针域,既可以保存右边的节点地址(后继),也可以保存左边的节点地址(前驱)。如果指针域指向一个不存在的节点,则将其指针置为NULL。。原创 2022-02-03 22:16:20 · 1306 阅读 · 0 评论 -
线性表-带头结点的单链表
链表的特点是一种物理存储结构上非连续、非顺序的存储结构。为了表示每个数据节点与其后继节点之间的逻辑关系,每个节点被分为数据域和指针域。数据域用来存储当前数据元素的信息,指针域用来存储下一个节点的地址。下面是带头结点的单链表的结构:结构体设计:typedef int ELEM_TYPE; typedef struct Node{ ELEM_TYPE data; //数据域 (1.头结点: 不保存任何数据 2.有效数据节点:保存有效值) struct No原创 2022-01-26 18:35:33 · 929 阅读 · 0 评论 -
顺序表的构建(2)不定长顺序表
不定长顺序表:它与定长数据表最大的区别就是它可以进行动态扩容,因此需要用malloc实现不定长顺序表的结构体设计中,与定长顺序表不同的地方在于首先将静态数组换成保存malloc返回值的指针,其次要增加一个变量用来存储当前最大空间个数如下图所示:结构体设计如下:typedef int ELEM_TYPE; typedef struct Desqlist{ ELEM_TYPE* elem; //指针,用来接收mallloc返回值 int length; //当前有.原创 2022-01-14 12:00:00 · 111 阅读 · 0 评论 -
顺序表的构建(1) 定长顺序表
线性表:唯一的头,唯一的尾,除了头结点,剩下其它节点都有前驱,除了尾结点,剩余其它节点都有后即顺序表可分为定长顺序表和不定长顺序表。顺序表的特点:顺序表特点:(插入删除操作较少,随机访问数组中值这个操作较多)1.逻辑简单,实现简单2.插入操作时间复杂度O(n),因为需要向前覆盖数据,但是尾插不需要挪动数据(尾删除时间复杂度O(1))3.删除操作时间复杂度O(n),因为需要向前覆盖数据,但是尾删除不需要挪动数据(尾删时间复杂度O(1))4.随机访问时间复杂度O(1),因为顺序表可以通过下标原创 2022-01-13 19:58:51 · 243 阅读 · 0 评论