![](https://img-blog.csdnimg.cn/20201014180756724.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
数据结构与算法
文章平均质量分 84
咖啡Q伴侣
纸上得来终觉浅,绝知此事要躬行! 代码虐我千百遍,我视代码如初恋!
展开
-
第三篇:汉诺塔算法——C语言递归实现
汉诺塔的递归实现算法,将A中的圆盘借助B圆盘完全移动到C圆盘上,每次只能移动一个圆盘,并且每次移动时大盘不能放在小盘上面递归函数的伪算法为如下:if(n == 1) 直接将A柱子上的圆盘从A移动到Celse 先将A柱子上的n-1个圆盘借助C柱子移动到B柱子上 直接将A柱子上的第n个圆盘移动到C柱子上 最后将B柱子上的n-1个圆盘借助A柱子移动到C柱子原创 2017-08-20 09:26:40 · 3536 阅读 · 0 评论 -
第十九篇:内部排序之四:归并排序和快速排序(含完整源码)
前言 之所以把归并排序和快速排序放在一起探讨,很明显两者有一些相似之处:这两种排序算法都采用了分治的思想。下面来逐个分析其实现思想。归并排序 实现思想 归并的含义很明显就是将两个或者两个以上的有序表组合成一个新的有序表。归并排序中一般所用到的是2-路归并排序,即将含有n个元素的序列看成是n个有序的子序列,每个子序列的长度为1,而后两两合并,得原创 2017-08-19 23:28:14 · 278 阅读 · 0 评论 -
第十八篇:内部排序之三:堆排序(含完整源码)
前言 堆排序、快速排序、归并排序(下篇会写这两种排序算法)的平均时间复杂度都为O(n*logn)。要弄清楚堆排序,就要先了解下二叉堆这种数据结构。本文不打算完全讲述二叉堆的所有操作,而是着重讲述堆排序中要用到的操作。比如我们建堆的时候可以采用堆的插入操作(将元素插入到适当的位置,使新的序列仍符合堆的定义)将元素一个一个地插入到堆中,但其实我们完全没必要这么做,我们有执行操作更少的方法,后原创 2017-08-19 23:27:10 · 170 阅读 · 0 评论 -
第十七篇:内部排序之二:冒泡排序和选择排序(改进优化,附完整源码)
前言 之所以把冒泡排序和选择排序放在一起,是因为二者的实现代码很相似,而且都是最基本的排序方式,非常容易理解和实现。当然,如果仅仅是为了讲述这两种排序方式,那也根本没必要写这篇博文了。和上篇博文一样,我会在冒泡排序和选择排序原始代码的基础上给出一些改进和优化,这才是本文的重点所在。原始冒泡排序 冒泡排序的思想很简单,如果要求排序后序列中元素按照从小到大的顺序排列,则原创 2017-08-19 23:26:06 · 220 阅读 · 0 评论 -
第十六篇:内部排序之一:插入排序和希尔排序的N中实现(不断优化,附完整源码)
前言 本来想将所有的内部排序总结为一篇博文,但是随着研究的深入,还是放弃了这个念头,斟前酌后,还是觉得分开来写比较好,具体原因,看完本篇博文也就自然明了了。 本篇文章主要探讨插入排序和希尔排序,之所将二者放在一起,很明显,是因为希尔排序是建立在插入排序的基础之上的。 注:以下各排序算法的N种实现方法大部分都是我根据算法思想,自己写出来的,或者是参考其本身的经典实现,我原创 2017-08-19 23:24:59 · 242 阅读 · 0 评论 -
第十五篇:二叉排序树C实现(含完整源码)
二叉排序树简介 二叉排序树(Binary Sort Tree,简称BST),又称二叉查找树,是红黑树、AVL树等的基础。它或是一棵空树,或者是具有下列性质的一棵二叉树: 1、若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 2、若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值; 3、它的左右子树也分别为二叉排序树。 下面的一原创 2017-08-19 23:24:02 · 577 阅读 · 0 评论 -
第十四篇:自己动手实现图的BFS和DFS(附完整源码)
图的存储结构 本文的重点在于图的深度优先搜索(DFS)和广度优先搜索(BFS),因此不再对图的基本概念做过多的介绍,但是要先大致了解下图的几种常见的存储结构。 邻接矩阵 邻接矩阵既可以用来存储无向图,也可以用来存储有向图。该结构实际上就是用一个二维数组(邻接矩阵)来存储顶点的信息和顶点之间的关系(有向图的弧或无向图的边)。其描述形式如下:[cpp]原创 2017-08-19 23:22:59 · 642 阅读 · 0 评论 -
第十三篇:模式匹配——从BF算法到KMP算法(附完整源码)
模式匹配 子串的定位操作通常称为串的模式匹配。模式匹配的应用很常见,比如在文字处理软件中经常用到的查找功能。我们用如下函数来表示对字串位置的定位:int index(const string &Tag,const string &Ptn,int pos) 其中,Tag为主串,Ptn为子串(模式串),如果在主串Tag的第pos个位置后存在与子串Ptn相同的子串,返回它在主原创 2017-08-19 23:21:54 · 575 阅读 · 0 评论 -
第十二篇:Huffman树&&Huffman编码(附完整源码)
Huffman Tree简介 赫夫曼树(Huffman Tree),又称最优二叉树,是一类带权路径长度最短的树。假设有n个权值{w1,w2,...,wn},如果构造一棵有n个叶子节点的二叉树,而这n个叶子节点的权值是{w1,w2,...,wn},则所构造出的带权路径长度最小的二叉树就被称为赫夫曼树。 这里补充下树的带权路径长度的概念。树的带权路径长度指树中所有叶子节点到根节点的原创 2017-08-19 23:20:35 · 541 阅读 · 0 评论 -
第十一篇:二叉树的层序遍历
前面有篇博客详细分析了二叉树三种遍历(前序、中序、后序)方式的递归与非递归实现,参见:http://blog.csdn.net/u012426327/article/details/77418101,但把二叉树的层序遍历算法给漏掉了,实际上也不能说漏掉了,毕竟层序遍历的实现方法与这三种遍历的实现方法有所不同,因此单独拿出来分析比较合适。 二叉树的层序遍历的实现还是比较简单的,由于其层级的原创 2017-08-19 23:17:05 · 205 阅读 · 0 评论 -
第十篇:二叉树递归与非递归遍历(附完整源码)
二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的。二叉树有前、中、后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的)。下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现。一、三种遍历方式原创 2017-08-19 23:15:59 · 225 阅读 · 0 评论 -
第二十篇:内部排序之五:计数排序、基数排序和桶排序(含完整源码)
前言 最后三种排序算法了,由于都不是基于比较的排序,因此这三种排序算法可以以线性时间运行。但是因为限制条件的特殊性,因此应用面没有基于元素比较的排序算法广,但是在很多特定的情况下还是蛮有用途的,而且效率极高。计数排序 计数排序是建立在这样的前提条件下的:假设n个输入元素的每一个都是0到k区间内的一个整数,其中k为某个整数。因此我们后面所写的程序也只是针对0到k之间的原创 2017-08-19 23:29:22 · 216 阅读 · 0 评论 -
第二十一篇:内部排序总结(附各种排序算法源码)
内部排序总结 这篇博文我们简要地总结下各种内部排序方法。 这10种排序算法中,前面7种属于建立在“比较”基础上的排序算法,通过决策树已经证明,任何基于比较进行的排序算法的时 间复杂度不可能再优于O(n*logn)。后面3种不是建立在比较的基础上的,因此,可以达到线性运行时间。 下面我们给出各种排序方法的时空复杂度的表格(属于自己总结,有不对的地方,希望大家指正原创 2017-08-19 23:30:02 · 239 阅读 · 0 评论 -
第七篇:静态链表的游标实现
以前学习的各种链表都是由指针实现的,链表中结点的分配和回收(即释放)都是由系统提供的标准函数malloc和free动态实现的,故称之为动态链表。但是有的高级语言,如BASIC、FORTRAN等,没有提供”指针”这种数据类型,此时若想采用链表做存储结构,就必须使用”游标”来模拟指针,由程序员自己编写”分配结点”和”回收结点”的过程。 用游标实现链表,其方法是:定义一个较大的结构数组作为原创 2017-08-19 23:11:59 · 991 阅读 · 0 评论 -
第八篇:浅谈尾递归
在《数据结构与算法分析:C描述》(Data Structures and Algorithm Analysis In C)的第三章中,以打印链表为例,提到了尾递归(tail recursion)并指出了尾递归是使用递归极其不当的例子,它指出虽然编译器会对尾递归自动优化,但即便如此最好还是不要去写尾递归。而我在《算法精解:C语言描述》(Mastering Algorithms with C)原创 2017-08-19 23:13:09 · 272 阅读 · 0 评论 -
数据结构与算法汇总
不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!数据结构与算法浅析线性递归和尾递归排序算法——快速排序汉诺塔算法——C语言递归实现基本数据结构——队列的顺序表示基本数据结构——线性表的链式表示基本数据结构——栈的链式表示静态链表的游标实现浅谈尾递归基本数据结构——队列的链式表示二叉树递归与非递归遍历(原创 2017-08-25 09:03:46 · 554 阅读 · 0 评论 -
第九篇:基本数据结构——队列的链式表示
该队列为链式队列,初建队列时,队头和队尾均指向头结点,头结点中不存放数据,只存放指针,头结点的下一个节点才开始存放数据,这这样做的目的是为了在入队和出队时方便对队列的操作,而不用考虑特殊情况。C语言源代码[cpp] view plain copy#include #include typedef struct原创 2017-08-20 09:29:54 · 226 阅读 · 0 评论 -
第六篇:基本数据结构——栈的链式表示
以下为操作栈的算法,该栈为动态栈。在该栈中,pTop指向的节点中存放该栈的栈顶数据,pBottom指向的节点的上一个节点存放该栈的栈底数据,pBottom指向的节点中不存放有效数据,这样做的目的是为了在进行入栈和出栈时方便对栈的操作,而不用考虑特殊情况操作系统:ubuntu编译软件:gcc结果截图:源代码:[cpp] view plain原创 2017-08-20 09:28:36 · 172 阅读 · 0 评论 -
第五篇:基本数据结构——线性表的链式表示
以下为操作链表的算法,该链表为动态单链表。链表以头指针为索引,头指针指向头节点,头节点指向首节点,以此类推,直到尾节点。头节点中不存放数据,只存放指向首节点的指针,设置头节点的目的是为了方便对链表的操作,如果不设置头节点,而是直接由头指针指向首节点,这样在对头指针后的节点进行插入删除操作时就会与其他节点进行该操作时有所不同,便要作为一种特殊情况来分析操作系统:ubuntu原创 2017-08-20 09:28:05 · 211 阅读 · 0 评论 -
第四篇:基本数据结构——队列的顺序表示
以下为操作队列的算法,该队列为静态队列,用循环数组实现。给该队列分配的内存长度为len+1,但实际只用了len个内存空间来保存数据,这样做是为了更方便判断队列的满与空。队列中front位置中存放的是队首的数据,rear位置的前一个位置中存放队尾的数据,而rear位置中则没有数据存放,这样做的目的是为了在入队和出队时方便对队列的操作,而不用考虑特殊情况操作系统:ubuntu编译软原创 2017-08-20 09:27:15 · 233 阅读 · 0 评论 -
第二篇:排序算法——快速排序
快速排序算法,以升序为例操作系统:ubuntu编译软件:gcc结果截图:源代码:[cpp] view plain copy#include void quickSort(int *,int,int); int findPoss(int *,int,int); int main()原创 2017-08-20 09:25:57 · 220 阅读 · 0 评论 -
第二十三篇:字典树(附完整源码)
字典树简介 字典书(Trie Tree),又称单词查找树,是键树的一种,典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。 字典树有3个基本性质: 1、根节点不包含字符,其余的每个节点都包含一个字符; 2、从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 3、每个节点的所有子原创 2017-08-19 23:32:26 · 372 阅读 · 0 评论 -
第二十二篇:HashTable相关操作实现(附完整源码)
前言 学过Java的人肯定对Hash这个词非常之熟悉,HashTable、HashSet、HashMap等都是对哈希表的封装或改进。这次我们来看下哈希表用C语言表示的封装实现。哈希表 哈希表又叫散列表,是实现字典操作的一种有效数据结构。哈希表的查询效率极高,在没有冲突(后面会介绍)的情况下不需经过任何比较,一次存取便能得到所查记录,因此理想情况下,查找一个元原创 2017-08-19 23:31:25 · 399 阅读 · 0 评论 -
第一篇:浅析线性递归和尾递归
今天一直在研究尾递归,看了些博文,记下点笔记,供以后复习用线性递归:也即是普通递归,单向递归,线性递归函数的最后一步操作不是递归操作,而是其他的操作。当数据量很大的时候,会造成栈溢出,这是因为,在每次递归调用时,递归函数中的参数,局部变量等都要保存在栈中,如果数据量很大的话,便可能会溢出。尾递归:也即是线性迭代,尾递归函数的最后一步操作是递归,也即在进行递归之前,把全部的操作先执行原创 2017-08-19 23:05:11 · 294 阅读 · 0 评论