数据结构与算法
文章平均质量分 94
车子 chezi
乐于开源,善于分享。死磕自己,方便大家。广泛查阅,独立思考。持续琢磨,自成一家。
展开
-
链表之CIRCLEQ
文章目录头文件例子代码分析CIRCLEQ_ENTRY 和 CIRCLEQ_HEADCIRCLEQ_HEAD_INITIALIZERCIRCLEQ_FIRST 和 CIRCLEQ_LASTCIRCLEQ_PREV 和 CIRCLEQ_NEXTCIRCLEQ_INITCIRCLEQ_EMPTYCIRCLEQ_INSERT_TAILCIRCLEQ_INSERT_HEADCIRCLEQ_INSERT_AFTERCIRCLEQ_INSERT_BEFORECIRCLEQ_FOREACHCIRCLEQ_FOREACH_R原创 2022-02-13 13:10:31 · 1530 阅读 · 0 评论 -
链表之TAILQ
文章目录TAILQ 介绍头文件举例代码分析TAILQ_ENTRY 和 TAILQ_HEADTAILQ_INITTAILQ_INSERT_HEADTAILQ_INSERT_TAILTAILQ_INSERT_AFTERTAILQ_INSERT_BEFORETAILQ_REMOVETAILQ_FOREACHTAILQ_FOREACH_REVERSE参考资料TAILQ 介绍TAILQ 队列是 FreeBSD 内核中的一种队列数据结构,在一些著名的开源库中(如 DPDK、libevent)有广泛的应用。TAI原创 2022-02-13 13:02:33 · 2313 阅读 · 0 评论 -
链表之STAILQ
文章目录STAILQ 示意图接口和实现举例代码分析STAILQ_ENTRY 和 STAILQ_HEADSTAILQ_INIT 和 STAILQ_INSERT_HEADSTAILQ_INSERT_TAILSTAILQ_INSERT_AFTERSTAILQ_REMOVESTAILQ_FIRST 和 STAILQ_REMOVE_HEADSTAILQ_FOREACHSTAILQ_NEXTSTAILQ_EMPTYSTAILQ_LASTSTAILQ 示意图STAILQ 和 LIST 的不同是,head 里面有个指原创 2022-02-13 12:33:22 · 3226 阅读 · 0 评论 -
链表之LIST
文章目录LIST 示意图接口和实现举例代码分析LIST_ENTRY 和 LIST_HEADLIST_INIT 和 LIST_INSERT_HEADLIST_INSERT_AFTERLIST_INSERT_BEFORELIST_FOREACHLIST_REMOVELIST_FIRST 和 LIST_NEXT参考资料上一篇博文 链表之SLIST_车子(chezi)-CSDN博客 说过,queue.h 里面有 5 种链表,分别是:SLISTLISTSTAILQTAILQCIRCLEQ这篇文章说原创 2022-02-13 12:29:20 · 1226 阅读 · 0 评论 -
链表之SLIST
文章目录背景SLIST 简介接口和实现举例代码分析SLIST_ENTRY 和 SLIST_HEADSLIST_INITSLIST_INSERT_HEADSLIST_INSERT_AFTERSLIST_REMOVESLIST_FIRST 和 SLIST_REMOVE_HEADSLIST_FOREACHSLIST_EMPTY 和 SLIST_INIT附录 queue.h参考资料背景对于 C 语言,在编程中需要用到链表时,通常需要程序员重新设计链表的结构体。这样做不仅麻烦,且需要验证代码的正确性,对于每个阅读原创 2022-02-13 12:22:33 · 3104 阅读 · 1 评论 -
快速排序的时间复杂度分析
快速排序的时间复杂度分析先说结论:最坏情况:O(N2)O(N^{2})O(N2)最好情况和平均情况:$ O(NlogN)$下面开始分析。假设一个序列共有 N 个元素,基本的快速排序的关系式是:T(N)=T(i)+T(N−i−1)+cNT(N) = T(i) + T(N -i -1) + cN T(N)=T(i)+T(N−i−1)+cN其中 i 表示一次划分后,枢纽所在的位置。对一个有 N 个元素的序列排序,其时间可以划分为 3 部分:1)把枢纽放到合适的位置,即其左边的数都小于等于它,右边的原创 2021-04-03 21:45:19 · 10244 阅读 · 1 评论 -
快速排序
文章目录原理讲解C 语言实现添加调试信息时间复杂度原理讲解假设我们现在对“6 1 2 7 9 3 4 5 10 8”这 10 个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被“基准数”这个名词吓到了,其实就是一个用来参照的数,看到后面你自会明白)。我有选择困难症,就让第一个数 6 作为基准数吧。接下来,需要将这个序列中所有比基准数 6 大的数放在它的右边,比基准数 6 小的数放在它的左边,类似下面这种排列:3 1 2 5 4 6 9 7 10 8如原创 2021-04-03 21:36:06 · 644 阅读 · 0 评论 -
二叉树的构建
文章目录什么是扩充二叉树扩充二叉树的前序遍历二叉树构建:前序 + 中序二叉树构建:后序 + 中序二叉树构建:层序 + 中序二叉树构建:扩充二叉树前序二叉树构建:扩充二叉树后序参考资料先复习一下二叉树的遍历:前序遍历:根结点—>左子树 —>右子树中序遍历:左子树—>根结点 —>右子树后序遍历:左子树 —>右子树 —>根结点如果知道了某个遍历序列,能否还原出那个二叉树呢?要构建一棵二叉树,仅靠前序、中序和后序中的任何一个都不能,因为不能唯一确定一棵二叉树。二叉树原创 2021-01-01 09:52:40 · 8272 阅读 · 0 评论 -
不带头节点的单链表如何头插(多图易懂)
文章目录缘起带头节点的头插不带头节点的头插错误的代码为什么错误如何修改返回新的头指针二级指针缘起本文想说的是单向非循环链表的头插。单向非循环链表,可以是带头节点的,也可以是不带头节点的。对于前者,代码比较简单,后文会说。对于后者,不带头节点的单向链表的头插,我发现即使有多年工作经验的老鸟,也可能写出错误的代码。带头节点的头插#include <stdio.h>#include <assert.h>#include <stdlib.h>typedef s原创 2020-11-22 21:22:08 · 13051 阅读 · 4 评论 -
浅谈尾调用和尾递归(C语言)
什么是尾调用在计算机科学里,尾调用是指一个函数里的最后一个动作是一个函数调用的情形,即这个调用的返回值直接被当前函数返回的情形。这种情形下称该调用位置称为“尾位置”。说得通俗点,尾调用就是指某个函数的最后一步是调用另一个函数。这个调用位置称为“尾位置”。比如有个函数叫fun,其实现是:int fun(void){ foo();}上面代码中,函数fun的最后一步是原创 2018-01-07 21:58:20 · 2715 阅读 · 2 评论 -
看懂堆排序——堆与堆排序(三)
看懂堆排序——堆与堆排序(三)看懂堆排序——堆与堆排序(三)堆排序的基本思想代码详解父亲下标和孩子下标的关系打印数组的函数下滤函数构造堆的函数删除最大元函数排序主函数完整代码及运行截图参考资料有了前面两篇文章的铺垫,堆与堆排序(一)堆与堆排序(二) 我们终于可以学习“堆排序”了。假使给定一个数组a[N],其包含元素a[0],a[1],...原创 2018-05-09 20:37:56 · 994 阅读 · 0 评论 -
希尔排序(一)
什么是希尔排序C语言实现数组打印函数排序函数测试函数运行结果参考资料希尔排序的名称源于它的发明者——唐纳德·希尔(Donald Shell)。希尔排序是另一种形式的插入排序,它神奇地突破了冒泡排序、直接选择排序、直接插入排序等算法的二次时间界限,在时间复杂度上首次实现了质的突破。希尔排序如此神奇,这源于它对插入排序两个优点的综合应用:在数据量少的时候插...原创 2018-05-09 23:08:52 · 673 阅读 · 0 评论 -
堆与堆排序(一)
堆与堆排序(一)上一篇博文 浅谈优先队列 介绍了什么是优先队列,文末提到了一种数据结构——“堆”,基于“堆”实现的优先队列,出队和入队的时间复杂度都为 O(logN).这篇博文我们就走进“堆”,看看它到底是什么结构。此堆非彼堆值得注意的是,这里的“堆”不是内存管理中提到的“堆栈”的“堆”。前者的“堆”——准确地说是二叉堆,是一种类似于完全二叉树的数据结构;后者的“堆”是一种类似...原创 2018-05-06 00:31:30 · 965 阅读 · 1 评论 -
堆的C语言实现——堆与堆排序(二)
堆的C语言实现——堆与堆排序(二)堆的C语言实现——堆与堆排序(二)头文件初始化函数下滤函数1(递归)堆构造函数1(自底向上,递归)下滤函数2(非递归,交换法)下滤函数3(非递归,空穴法)堆构造函数2(自底向上,非递归,空穴法)自顶向下堆构造插入函数1(交换法)插入函数2(空穴法)堆构造函数3(自顶向下,空穴法)删除最大键函数完整的代码及运行截图上...原创 2018-05-06 21:57:27 · 1949 阅读 · 1 评论 -
希尔排序(二)
另一种写法上一篇博文希尔排序(一)中的代码是基于希尔排序的原理,“直译”过来的。还有一种更简单的写法:void shellsort_2(int a[], int n) { int j, gap; for (gap = n / 2; gap &gt; 0; gap /= 2) {#ifdef PRINT_PROCEDURE ...原创 2018-05-19 23:48:13 · 376 阅读 · 0 评论 -
浅谈优先队列
浅谈优先队列一道面试题如果你被问到: “编写一个程序,从 10 亿个元素的整数数组中找出前10个最大的数。” 你会怎么回答?我想,最最简单的回答就是蛮力法:先对这10亿个数排序(比如用时间复杂度为 O(nlogn)O(nlogn)O(n \log n) 的快速排序),然后选出前10个最大的。请问有更好的方法吗?优先队列是什么普通的队列是一种先进先出的数据结构:...原创 2018-04-28 23:02:46 · 578 阅读 · 0 评论 -
选择问题(求第k个最小元素)
什么是选择问题划分的思路Lomuto 划分利用划分求第k小元素C语言实现改进参考资料什么是选择问题选择问题(selection problem)是求一个n个数列表的第k个最小元素的问题。这个数字被称为第k个顺序统计量(order statistic)。当然,对于k=1或者k=n的情况,我们可以扫描整个列表,找出最小或者最大的元素。对于其他情况,我们可以对列表进行排序...原创 2018-05-27 16:48:20 · 12039 阅读 · 1 评论 -
二分查找的递归和非递归算法(C语言实现)
二分查找的用途二分查找又称折半查找,它用来解决“在一堆数中找出指定的数(也可能找了,发现没有)”这类问题。二分查找的应用条件要应用二分查找,这“一堆数”必须有以下特征:存储在数组中 有序排列所以,如果数是用链表存储的,那就无法在其上应用二分查找。 至于是升序排列还是降序排列、数组中是否存在相同的元素都不要紧。在本文的实验中,我们使数组递增排列,且数组中的元素互不相同。原创 2018-01-06 18:34:17 · 13632 阅读 · 2 评论 -
单链表入门(二)
上篇博文,介绍了线性表、单链表等概念。这篇博文,我们就写代码来实现带头结点的非循环单链表。原创 2017-12-02 21:55:36 · 438 阅读 · 0 评论 -
单链表入门(一)
什么是线性表什么是单链表原创 2017-12-02 15:37:41 · 500 阅读 · 0 评论 -
C语言实现通用链表初步(二)
接着上次的内容,我们继续!原创 2014-04-30 17:06:21 · 937 阅读 · 0 评论 -
C语言实现通用链表初步(三)----单元测试
前两节,我们已经完成了链表的一些操作,快来测试一下吧。这里使用的单元测试gong'j原创 2014-05-19 10:36:06 · 1009 阅读 · 0 评论 -
用双向链表实现一个栈
前面我们已经造好了一个轮子原创 2014-06-18 12:11:34 · 1964 阅读 · 1 评论 -
二叉查找树的C语言实现(一)
什么是二叉查找树?原创 2014-07-08 14:23:24 · 1009 阅读 · 0 评论 -
二叉查找树的C语言实现(二)
接着上次的话题。这次我们要讨论,二叉原创 2014-08-23 16:37:30 · 685 阅读 · 0 评论 -
程序员面试系列——单链表的反转
单向链表的反转(或者叫逆置)是经常被问到的考题。建议考前临阵磨枪,强背一波。代码说明:void reverse_list(node_t *head)此函数实现带头结点(也叫表头、哑结点)的单链表的反转。 head是头结点的地址。原创 2017-07-12 23:17:43 · 522 阅读 · 0 评论 -
程序员面试系列——冒泡排序
虽然冒泡排序是排序算法里面最简单的一种,但是不可轻视。我在应届生的面试和社招的面试中,都被问到了冒泡排序。基本思想:冒泡排序属于蛮力法,它比较表中的相邻元素,如果它们是逆序的话就交换它们的位置。重复多次后,最终,最大的元素就“冒”到列表的最后一个位置。第二遍操作将第二大的元素“冒”出来。这样一直重复,直到n-1遍(列表共有n个元素)以后,该列表就排序好了。原创 2017-07-23 21:43:19 · 1579 阅读 · 0 评论 -
程序员面试系列——合并排序(递归实现)
合并排序,或者叫归并排序,在算法思想中属于分治法。对于一个需要排序的数组,合并排序把它一分为二,并对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序数组。本文要介绍两种实现,都是基于递归(自顶向下)。这两种实现没有本质的差别,第二种只是为了节省内存,提高效率。原创 2017-08-09 00:21:40 · 915 阅读 · 0 评论 -
程序员面试系列——选择排序
选择排序也属于蛮力法。 首先,扫描整个列表,找到最小的元素,将其和第一个元素交换位置;然后从第二个元素开始扫描列表,找到最小的元素,再将其和第二个元素交换位置……直到从倒数第二个元素开始扫描列表,找到最小的元素,将其和倒数第二个元素交换位置。原创 2017-07-24 22:26:50 · 421 阅读 · 0 评论 -
程序员面试系列——约瑟夫环
约瑟夫斯问题(Josephus Problem)约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为“约瑟夫环”,也有的地方叫做“丢手绢”。问题是这样的: 有编号从1 到n的 n个人围坐成一圈。从编号为1的人开始报数,报到 m 的人出局,下一位再从 1 开始报数,报到 m 的人出局,……如此持续,直到剩下一人为止。原创 2017-07-17 22:39:14 · 1352 阅读 · 0 评论 -
合并排序的非递归实现(自底向上设计)
上一篇博文,讨论了合并排序的递归实现。这篇文章,说说合并排序的非递归实现。原创 2017-08-22 23:41:00 · 1600 阅读 · 1 评论 -
活用内核链表解决约瑟夫斯问题
约瑟夫斯问题(有时也称为约瑟夫斯置换),是一个出现在计算机科学和数学中的问题。在计算机编程的算法中,类似问题又称为“约瑟夫环”,也有的地方叫做“丢手绢”。问题是这样的: 有编号从1到n的n个人围坐成一圈。从编号为1的人开始报数,报到m的人出局,下一位再从 1 开始报数,报到 m 的人出局,……如此持续,直到剩下一人为止,假设此人的原始编号是x。给定 n和 m,求出x。原创 2017-09-07 23:14:06 · 562 阅读 · 0 评论 -
队列的C语言实现(通过内核链表)
win7操作系统+Keil 5 IDE. 用内核链表实现通用队列;适合单片机程序;原创 2017-09-19 21:29:12 · 1556 阅读 · 0 评论 -
程序员面试系列——插入排序
插入排序在算法思想中属于“减治法”。减治法的基本思想是:规模为n的原问题的解与较小规模的子问题的解之间具有某种关系。由于存在这种关系,所以只需求解其中一个较小规模的子问题就可以得到原问题的解。插入排序就是基于“减治法”中的“减一技术”实现的。原创 2017-07-26 21:48:54 · 702 阅读 · 0 评论 -
双向循环链表的选择排序
以Linux内核链表为例,进行选择排序原创 2017-11-30 20:55:45 · 1805 阅读 · 0 评论 -
双向循环链表的插入排序
前两篇博文,我讨论了链表的冒泡排序和选择排序(以Linux内核链表为例),这篇文章,我想说说插入排序。原创 2017-11-30 21:55:53 · 4299 阅读 · 0 评论 -
双向循环链表的冒泡排序
以内核链表为例,进行冒泡排序原创 2017-11-28 21:15:58 · 7239 阅读 · 1 评论 -
C语言实现通用链表初步(一)
假设不采用Linux内核链表的思路,怎样用C原创 2014-04-30 15:12:34 · 1359 阅读 · 1 评论