1.1 冒泡排序 说起冒泡排序,这也算是在我们学习编程时遇到的第一个排序算法,总体逻辑就是从待排序数组第一个一直向后遍历,遇到比自己大的就记录该值,遇到比自己小的就交换,直到到达待排序数组结尾,此时待排序数组长度...,发现与二叉树前序遍历规则非常像,我们可以参照二叉树前序遍历(如有疑问请参考:【数据结构和算法】— 二叉树(3)–二叉树链式结构的实现(1))规则即可快速写出来,后序只需分析如何按照基准值来对区间中数据进行划分的方式即可...根据其特性,元素集合越接近有序,直接插入排序算法的时间效率越高。且此时待排序数组的元素个数较少,不适合希尔排序,且他是一种稳定的排序算法。...1.4 快排非递归版 根据递归版快排的特性,相当于二叉树的前序遍历,那么我们便可利用栈后进先出的特性,来模拟递归并实现排序,栈的实现还请参考:【数据结构和算法】— 栈。...基本思想: 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。
[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。...此处的排序便是由排序算法实现,下面将对不同的排序算法进行剖析。 1.3 常见的排序算法 下面将基于c语言,对以上七种排序逐一实现。...希尔排序的时间复杂度不好计算,因为gap的取值方法很多,导致很难去计算,因此在好些书中给出的希尔排序的时间复杂度都不固定: 《数据结构(C语言版)》— 严蔚敏 《数据结构-用面相对象方法与C+...实际中很少使用 时间复杂度: O(N^2) 空间复杂度: O(1) 稳定性: 不稳定 3.2 堆排序 堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。...因为之前已经介绍过了,所以这里就不多讲了,详细请参考:【数据结构和算法】—二叉树(2)–堆的实现和应用 直接选择排序的特性总结: 堆排序使用堆来选数,效率就高了很多。
大家好,又见面了,我是你们的朋友全栈君。 简单的哈希表实现 这是一个简单的哈希表的实现,用c语言做的。 原理 先说一下原理。 先是有一个bucket数组,也就是所谓的桶。...通过散列算法,将字符串的key映射到某个桶中,这个算法是确定的,也就是说一个key必然对应一个bucket。 然后是碰撞问题,也就是说多个key对应一个索引值。...举个例子:有三个key:key1,key3,key5通过散列算法keyToIndex得到的索引值都为2,也就是这三个key产生了碰撞,对于碰撞的处理,采取的是用链表连接起来,而没有进行再散列。...这是包含的头文件 #include #include #include #define BUCKETCOUNT 16 哈希表和节点数据结构的定义 struct hashEntry { const...,因为C标准库中string.h中有一系列这样的函数。
第一只熊把这堆苹果平均分为N份,多了一个,它把多的一个扔了,拿走了一份。...第二只熊把剩下的苹果又平均分成N份,又多了一个,它同样把多的一个扔了,拿走了一份,第三、第四直到第N只熊都是这么做的,问果园里原来最少有多少个苹果?...示例和说明如下: 2、解题思路 我的方法很简单就是从最小的可能的数开始,一个一个尝试,满足了测试的要求之后,就退出循环把这个符合条件的值给找出来,因为是从最小的可能的数开始尝试那么符合条件的肯定就是最小的值了...3、算法实现 #include int main() { int n; fscanf(stdin, "%d", &n); /* 输入熊的个数 */ int i, temp;...n - 1; } if(cnt == n) { break; } } fprintf(stdout, "%d", old); return 0; } 附加: 在网上找到的一个高手的解法
链表 一个假设 线性表是一种线性结构,它是具有相同类型的n(n≥0)个数据元素组成的有限序列。如果你之前没有学过链表肯定先想到的是数组这一线性结构,那我们是否可以用数组实现链表的插入 删除 等操作。...n个数据那么我们就需要一定n次,耗用的时间周期为O(n) 尾部插入 这个没什么好说的,根据数组最后的索引的我们可以直接插入 但是最坏的情况是 数组的大小不足以我们在尾部 插入数据 这时候我们就需要重新创建一个更大的数组存放这些尾部增加的数据...C语言中可以用一个结构体来解释这两条 struct Node { int data; Node*next; } 结构体成员大小都是4字节 我们把这个结构体叫做节点 结构体第二个成员是指向节点的指针 也就是下一个节点的地址...数组和链表的区别 要明确一个原则,每个数据结构都有自己适合的场景,而没有绝对的谁比谁好这种说法,这与数据结构的频繁操作和数据量的大小等有关。...假如要存放的不再是一个简单四字节整型,而是一个复杂的数据结构,我们举例它占用16个字节,那么5x16 =80 而链表一个节点占用20X3 = 60 明显是链表对于存储复杂数据类型内存占用少于数组。
return false; } (*pStack)->pBuffer = (Coordinate *)malloc(sizeof(Coordinate) * STACK_CAPACITY);//栈内的元素的内存...Stack *pStack) { free(pStack->pBuffer);//释放容器释放掉 pStack->pBuffer = NULL; free(pStack);//释放掉容器中一个一个的元素的内存释放掉...,栈底是在元素的右下角,,因为是出栈pop,所以栈顶得--1,因为栈顶在左上角,出的是没有元素,得栈顶下来。...bool isFromButtom) { if(isFromButtom) { for(int i = 0; i length; i++) { //printf("%c...pStack->pBuffer[i])); } } else { for (int i = pStack->top - 1; i >= 0; i--) { //printf("%c
今天来介绍一下C语言中常见的一种数据结构——链表 如下是链表的结构示意图: 在链表中有一个头指针变量,图中head表示的就是头指针,这个指针变量保存一个地址。...也就是说头指针指向一个变量,这个变量就是量表的元素。在链表中每一个元素包括数据部分和指针部分。数据部分用来存放元素所包含的数据,而指针部分用来指向下一个元素。...最后一个元素的指针指向null,表示指向的地址为空。...从示意图中我们可以看到,head头结点指向第一个元素,第一个元素的指针指向第二个元素,第二个元素的指针又指向第三个元素,第三个元素的指针指向null。这样我们就可以通过头指针寻找链表中的元素。...下来我们通过一个具体的实例来深入地了解一下链表,编写一个学生信息的链表结构,并且将链表中的信息进行输出。
相关文章路径:C语言求字符串的长度->C语言字符串的复制-> C语言的字符串的联接->C语言字符串的比较->C语言查找字符->C语言BF算法->C语言输出字符串->C语言输入字符串 C语言标准函数库中包括...作为练习,我们自己编写一个功能与之相同的函数。...函数原型 char* StrStr(const char *txt, const char *pat); 说明:txt 和 pat 分别为主串和子串的起始地址。...若查找成功,则函数值为子串在主串中首次出现的起始地址,否则函数值为NULL。 特别地,我们对C语言库函数strstr进行适当修改:若子串为空串,则没有意义,函数值规定为NULL。...printf("%d\n", p - m); } else { puts("NULL"); } return 0; } /* 你提交的代码将被嵌在这里
大家好,又见面了,我是你们的朋友全栈君。 一、什么是二叉树 1.概述 首先,需要了解树这种数据结构的定义: 树:是一类重要的非线性数据结构,是以分支关系定义的层次结构。...2.名词解释 名称 含义 根节点 树的顶端结点 父节点 若一个节点含有子节点,则这个节点称为其子节点的父节点 子节点 具有相同父节点的节点 兄弟节点 彼此都拥有同一个父节点的节点 叶子节点 即没有子节点的节点...节点的权 即节点值 路节点的度 一个节点含有的子树的个数 树的度 一棵树中,最大的节点的度称为树的度 深度 根结点到这个结点所经历的边的个数 层数 该节点的深度+1 高度 结点到叶子结点的最长路径所经历的边的个数...对于二叉树的删除,有以下逻辑: 由于树的节点和节点之间的联系是单向的,对于要删除的节点,需要找到他的父节点进行删除 从根节点开始遍历节点,判断节点的左右子节点是否为目标节点 如果是就删除并返回 否则就持续向右或左递归...以下图的树为例: 假设数组为{1,2,3,4,5,6,7,},我们可以知道: 下标为n的元素的左节点为:2*n+1 下标为n的元素的右节点为:2*n+2 下标为n的元素的父节点为:(n-1)/2 如果给顺序存储二叉树写一个前序遍历急就是这样
只 允许在表的一端进行插入,而在另一端删除元素,如日常生活中的排队现象。队列中 允许插入的一端叫队尾(rear),允许删除的一端称队头(front)。...(二)队列的表示形式 队列的表示形式有两种:队列的链式表示、队列的顺序表示。 1.队列的链式表示 用链表来表示的队列,简称链队列。...特点是无法用动态 分配的一维数组实现循环队列。 (三)循环队列入队、出队实现思路 1.循环队列入队算法 入队算法过程为:判断队列是否已满?...如果已满则退出;否则,队尾指针加 1, 并在队尾插入新的元素。 2.循环队列出队算法 出队算法过程为:判断队列是否为空?如果为空则退出;否则,队头指针加 1,并删除队头元素。...(四)算法实现 队列的顺序表示 #define _CRT_SECURE_NO_WARNINGS #include #include #define MAX_SIZE
出队列:进行删除操作的一端称为队头 数据结构设计 首先,我们需要定义队列节点的数据结构和队列的数据结构: #include #include #include...,但是使用结构体封装的方式更符合常见的数据结构和面向对象编程的思想,能够提高代码的可读性、可维护性和易用性。...// 定义队列数据结构 typedef struct Queue { QNode* phead;//指向队列的头节点(队首) QNode* ptail;//指向队列的尾节点(队尾)。...} Queue; 对于队列这种数据结构,使用指向队列头部和尾部的指针以及队列大小的方式进行封装有以下好处: 封装性更好: 使用 Queue 结构体将队列的头部指针、尾部指针和大小封装在一起,更符合面向对象编程的思想..."true" : "false"); QueueDestroy(&queue); return 0; } 代码效果图: 总源代码 Queue.c #include "Queue.h
的左子树\n", bt->data); bt->l_chrild = Create_tree(); // printf("请输入 %c 的右子树\n",bt->data...跟,左,右,左子树的左孩子,左子树的右孩子,右子树的左孩子,右子树的右孩子,出对顺序就是这 int i, j; BT *q[100], *p; p = bt; if (...= j) // 当队列不为空时执行循环 { p = q[i]; printf("%c ",p->data); // 访问首结点的数据域 if...的左子树\n", bt->data); bt->l_chrild = Create_tree(); // printf("请输入 %c 的右子树\n",bt->data...= j) // 当队列不为空时执行循环 { p = q[i]; printf("%c ",p->data); // 访问首结点的数据域 if
4.1归并排序递归版本 4.2归并排序非递归版本 总结 ---- 前言 常见的排序算法如下: 一、插入排序 1.1直接插入排序 基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中...: 元素集合越接近有序,直接插入排序算法的时间效率越高 时间复杂度:O(N^2) 空间复杂度:O(1),它是一种稳定的排序算法 稳定性:稳定 1.2希尔排序 希尔排序法又称缩小增量法。...(非递归) 主要通过数据结构栈来模拟实现类似于二叉树的前序遍历 如果有同学对C语言实现栈不熟悉可以点一下链接:C源实现数据结构栈 具体代码如下: typedef int STDataType; typedef...} } for (int i = 0;i <= right;i++)//打印 { printf("%d ", a[i]); } } 四 归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法...,该算法是采用分治法(Divide andConquer)的一个非常典型的应用。
//以上搬运至郝斌老师数据结构中的视频知识,然后依样画葫芦去写的; //当然指针知识和链表的基础知识要先懂: //首先先创建链表,如下: #include #...退出程序\n”); exit(-1); //需要加头文件stdlib.h } PNODE pTail = pHead; //创建尾节点作为首节点,这个的作用在于后面将新创建的节点覆盖于尾节点...; exit(-1); } printf(“请您输入要输入第%d的节点的值:”, i+1); scanf(“%d”, &val); pNew->data = val;...; //使新节点再次成为尾节点,和首次的步骤一样 } return pHead; } //其次,对链表的遍历是必须的; void traverse_list(PNODE pHead...:len = 5 请您输入要输入第1的节点的值:12 请您输入要输入第2的节点的值:34 请您输入要输入第3的节点的值:26 请您输入要输入第4的节点的值:44 请您输入要输入第5的节点的值
上一篇博文我们用指针实现了链表,但是诸如BASIC和FORTRAN等许多语言都不支持指针。如果需要链表而又不能使用指针,这时我们可以使用游标(cursor)实现法来实现链表。...在链表的实现中有两个重要的特点: 数据存储在一组结构体中。每一个结构体包含有数据以及指向下一个结构体的指针。...一个新的结构体可以通过调用malloc而从系统全局内存(global memory)得到,并可以通过free而被释放。 游标法必须能够模仿实现这两条特性 。...const Position P ); ElementType Retrieve( const Position P ); #endif /*_CUrsor_H */ 可以从上面的代码上看到,链表的游标实现跟链表的接口定义几乎是一样的...函数是对游标链表的测试。
/************************************************************************/ /* 树 课程要求:完成树的基本操作...树的创建和销毁 2. 树中节点的搜索 3. 树中节点的添加与删除 4....树中节点的遍历 BOOL CreateTree(Tree **pTree, Node *pRoot);//Tree **pTree 树,Node *pRoot 根节点...AddNode(Tree *pTree, int nodeIndex, int direction, Node *pNode);//int direction添加到左边还是右边 Node *pNode添加的节点...后序遍历演示 void TreeTraverse(Tree *pTree); //遍历 关于数组与树之间的算法转换
AVL(Adelson-Velskii 和 Landis)树是带有平衡条件的二叉查找树。在计算机科学中,AVL树是最先发明的自平衡二叉查找树。...在AVL树中任何节点的两个子树的高度最大差别为1,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下的时间复杂度都是O(lngn)。...节点的平衡因子是它的左子树的高度减去它的右子树的高度(有时相反)。带有平衡因子1、0或-1的结点被认为是平衡的。带有平衡因子-2或2的节点被认为是不平衡的,并需要重新平衡这个树。...平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。 AVL树的基本操作一般涉及运作同在不平衡的二叉查找树所运作的同样的算法。...但是要进行预先或随后做一次或多次所谓的"AVL旋转"。 以下图标表示的四种情况,就是AVL旋转中常见的四种。(图片用了维基百科的,不确定不开V**图是否会挂)。
方便自己的复习以及分享一些自己的学习过程。...的幂 367.有效的完全平方数 374.猜数字大小 414.第三大的数 509.斐波那契数 520.检测大写字母 1295.统计位数为偶数的数字 1346.检查整除及其两倍数是否存在 数据结构基础选填题...请你猜选出的是哪个数字。 如果你猜错了,我会告诉你,你猜测的数字比我选出的数字是大了还是小了。...1:我选出的数字比你猜的数字大 pick > num 0:我选出的数字和你猜的数字一样。...来源:力扣(LeetCode) 作为一个菜鸟,我想到的是两层for循环解决: 数据结构基础选填题 选择题 众所周知,单链表并不能像顺序表一样能够随机存取,访问元素是需要去遍历一遍的。
如下 图: (二)栈的的表现形式 栈有两种表示形式:栈的表示和实现、栈的 链式表示。 1.栈的表示和实现 利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。...非空栈顶指针始终在始终在栈顶元素 的下一个位置。 2.栈的链式表示 当栈的长度无法估计时最好用栈的链式表示,如下图所示。 结点包含数据元素和指针两个数据域。...(三)栈的链式表示时元素压入、弹出 算法实现思路 1.栈的线性链表的压入算法 压入算法过程为:定义新的结点 p、修改新结 点的指针(指向原栈顶结点 top)、给新结点 p 赋 值为 x、...2.栈的线性链表的弹出算法 弹出算法过程为:将栈顶结点 top 赋给 p、取结点 p 的值并赋给 x、调整栈顶位置(指向结点 p 的下一个结点)、释放结点 p 的空间。...(四)算法的实现 栈的顺序存储代码表示(已给出具体代码的注释): #define _CRT_SECURE_NO_WARNINGS #include #include
领取专属 10元无门槛券
手把手带您无忧上云