数据结构与算法
文章平均质量分 93
包含常见数据结构与算法相关的内容
s1mba
这个作者很懒,什么都没留下…
展开
-
数据结构:栈的顺序存储结构
栈(stack)是限定在表尾进行插入和删除操作的线性表。我们把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构。示例程序:(改编自《大话数据结构》) C++ Code 123456789101112原创 2013-04-22 19:57:44 · 3450 阅读 · 3 评论 -
算法:图的广度优先遍历(Breadth First Search)
图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traverse Graph)。图的遍历方法一般有两种,第一种是我们在前面讲过的《深度优先遍历(Depth First Search)》,也有称为深度优先搜索,简称为DFS。第二种是广度优先遍历(Breadth First Search),也有称为广度优先搜索,简称为B原创 2013-04-30 09:22:53 · 30975 阅读 · 4 评论 -
算法:图的深度优先遍历(Depth First Search)
图的遍历和树的遍历类似,我们希望从图中某一顶点出发访遍图中其余顶点,且使每一个顶点仅被访问一次,这一过程就叫做图的遍历(Traverse Graph)。图的遍历方法一般有两种,第一种是深度优先遍历(Depth First Search),也有称为深度优先搜索,简称为DFS。第二种是《广度优先遍历(Breadth First Search)》,也有称为广度优先搜索,简称为BFS。我们在《堆原创 2013-04-30 09:19:42 · 25057 阅读 · 5 评论 -
算法:AOV网(Activity on Vextex Network)与拓扑排序
在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称之为AOV网(Activity on Vextex Network)。AOV网中的弧表示活动之间存在的某种制约关系,AOV网中不能存在回路,让某个活动的开始要以自己完成作为先决条件,显然是不可以的。设G= { V, E }是一个具有n个顶点的有向图,V中的顶点序列v1, v2, ...,原创 2013-05-01 21:49:24 · 8435 阅读 · 0 评论 -
算法:图解最小生成树之普里姆(Prim)算法
我们在图的定义中说过,带有权值的图就是网结构。一个连通图的生成树是一个极小的连通子图,它含有图中全部的顶点,但只有足以构成一棵树的n-1条边。所谓的最小成本,就是n个顶点,用n-1条边把一个连通图连接起来,并且使得权值的和最小。综合以上两个概念,我们可以得出:构造连通网的最小代价生成树,即最小生成树(Minimum Cost Spanning Tree)。找连通图的最小生成树,经典的有两种原创 2013-04-30 21:32:02 · 43781 阅读 · 3 评论 -
数据结构:二叉树的遍历和存储结构
在《二叉树的定义和性质》中我们已经认识了二叉树这种数据结构。我们知道链表的每个节点可以有一个后继,而二叉树(Binary Tree)的每个节点可以有两个后继。比如这样定义二叉树的节点:typedef struct node *link;struct node { unsigned char item; link l, r;};这样的节点可以组织成下图所示的形态。原创 2013-04-28 15:03:11 · 4032 阅读 · 0 评论 -
数据结构:双向链表实现队列与循环链表
一、双向链表(double linked list)如图26.5,是在单链表的每个结点中,再设置一个指向其前驱结点的指针域。双向链表的基本操作与单链表基本一样,除了插入和删除的时候需要更改两个指针变量,需要注意的是修改的顺序很重要,插入如图3-14-5,删除如图3-14-6。链表的delete操作需要首先找到要摘除的节点的前趋,而在单链表中找某个节点的前趋需要从表头开始原创 2013-04-26 18:45:01 · 7065 阅读 · 0 评论 -
数据结构:线性表之链式存储结构
为了表示每个数据元素ai与其直接后继元素ai+1之间的逻辑关系,对数据ai,除了存储其自身的信息之外,还需存储一个指示其直接后继的信息(即直接后继的存储位置)。这两部分信息组成数据元素ai的存储映像,称为结点(Node)。N个结点链结成一个链表,即为线性表(a1,a2,...,an)的链式存储结构,因为此链表的每个节点中只包含一个指针域,所以叫做单链表。我们把链表中的第一个结点的存储位原创 2013-04-21 10:12:45 · 4501 阅读 · 0 评论 -
算法:快速排序以及第k小元素的线性选择算法
简要介绍下快速排序的思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。一.《data structure and algorithm analysis in c》中的实现,测试过,觉得该说明的已经注释 C++ C原创 2013-04-15 16:03:23 · 6173 阅读 · 0 评论 -
十种排序算法总结(冒泡、插入、选择、希尔、归并、堆、快速,计数,桶,基数)
首先声明一下,本文只对七种排序算法做简单总结,并参照一些资料给出自己的代码实现,并没有对某种算法理论讲解,更详细的了解可以参考以下资料(本人参考):1、《data structure and algorithm analysis in c 》2、《大话数据结构》3、http://blog.csdn.net/morewindows/article/details/7961256原创 2013-08-01 17:16:54 · 69870 阅读 · 19 评论 -
算法:静态查找表(Static Search Table)(顺序查找、二分查找、插值查找、斐波纳契查找)
查找表(Search table)是由同一类型的数据元素(或记录)构成的集合。关键字(key)是数据元素中某个数据项的值,又称为键值,用它可以表示一个数据元素,也可以标识一个记录的数据项(字段),称之为关键码。若此关键字可以唯一地标识一个记录,则称此关键字为主关键字(primary key)。而对于那些可以识别多个数据元素(或记录)的关键字,称为次关键字(Secondary Key),次关键字也可原创 2013-05-03 20:57:56 · 7145 阅读 · 12 评论 -
散列表(三):冲突处理的方法之开地址法(线性探测再散列的实现)
一、开地址法基本思想:当关键码key的哈希地址H0 = hash(key)出现冲突时,以H0为基础,产生另一个哈希地址H1 ,如果H1仍然冲突,再以H0为基础,产生另一个哈希地址H2 ,…,直到找出一个不冲突的哈希地址Hi ,将相应元素存入其中。这种方法有一个通用的再散列函数形式: 其中H0 为hash(key) ,m为表长,di称为增量序列。增量序列的取值方式不同,相应的原创 2013-07-31 12:49:45 · 39159 阅读 · 4 评论 -
散列表(二):冲突处理的方法之链地址法的实现(哈希查找)
首先需要澄清的一点是,这里讲的是hash table ,即数据项所存储的表要用数组来实现。一、链地址法这种基本思想:将所有哈希地址为i 的元素构成一个称为同义词链的链表,并将链表的头指针存在哈希表的第i个单元中,因而查找、插入和删除主要在同义词链中进行。 该散列方法首先对关键码集合用某一个散列函数计算它们的存放位置。若设散列表地址空间的所有位置是从0到m原创 2013-07-31 09:15:50 · 12594 阅读 · 2 评论 -
数据结构:二叉树的定义和性质以及特殊二叉树
一、二叉树(Binary Tree)是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。如图1就是一棵二叉树 图1二叉树的特点:(1)每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。(2)左子树和右子树是由顺序的,次序不能颠倒。(3)即使树中某结点只有一棵子树,也要区原创 2013-04-26 13:19:59 · 5089 阅读 · 0 评论 -
平衡二叉树 AVL 的插入节点后旋转方法分析
平衡二叉树 AVL( 发明者为Adel'son-Vel'skii 和 Landis)是一种二叉排序树,其中每一个节点的左子树和右子树的高度至多等于1。首先我们知道,当插入一个节点,从此插入点到树根节点路径上的所有节点的平衡都可能被打破,如何解决这个问题呢?这里不讲大多数书上提的什么平衡因子,什么最小不平衡子树,实际上让人(me)更加费解。实际上你首要做的就是先找到第一个出现不平衡的节点,也原创 2013-10-28 21:02:11 · 8526 阅读 · 0 评论 -
数据结构:树的定义和基本概念
一、树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一棵非空树中:(1)有且仅有一个特定的称为根(root)的结点。(2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1,T2,....,Tm, 其中每一个集合本身又是一棵树,并且称为根的子树(SubTree),如图1所示:图1树的定义之中还用到了树的概念,即递归定义。如图2中的子树T1和T2就是根原创 2013-04-26 09:26:01 · 17161 阅读 · 2 评论 -
算法:二叉排序树的删除节点策略及其图形化(二叉树查找)
二叉排序树(BST,Binary Sort Tree)具有这样的性质:对于二叉树中的任意节点,如果它有左子树或右子树,则该节点的数据成员大于左子树所有节点的数据成员,且小于右子树所有节点的数据成员。排序二叉树的中序遍历结果是从小到大排列的。二叉排序树的查找和插入比较好理解,主要来看一下删除时的情况。如果需要查找并删除如图8-6-8中的37, 51, 73,93这些在二叉排序树中是叶子的结点原创 2013-05-05 23:06:03 · 12253 阅读 · 0 评论 -
数据结构:队列的顺序存储结构(循环队列)
队列(Queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。是一种先进先出的线性表(FIFO)。允许插入的一端称为队尾,允许删除的一端称为队头。我们在《栈的顺序存储结构》中发现,栈操作的top指针在Push时增大而在Pop时减小,栈空间是可以重复利用的,而队列的front、rear指针都在一直增大,虽然前面的元素已经出队了,但它所占的存储空间却不能重复利用。但大多数程序并不是这样原创 2013-04-23 22:50:36 · 5100 阅读 · 2 评论 -
算法:字符串的KMP模式匹配
在朴素的模式匹配算法中,主串的pos值(i)是不断地回溯来完成的(见字符串的基本操作中的Index函数)。而计算机的大仙们发现这种回溯其实可以是不需要的。既然i值不回溯,也就是不可以变小,那么考虑的变化就是子串的pos值(j)了。通过分析发现子串中如果有相等字符,j值的变化就会不相同,也就是说,这个j值的变化跟主串其实没什么关系,关键就取决于子串的结构中是否有重复的问题。我们把子串各个位置的j原创 2013-04-25 19:41:01 · 2097 阅读 · 0 评论 -
散列表(四):冲突处理的方法之开地址法(二次探测再散列的实现)
前面的文章分析了开地址法的其中一种:线性探测再散列,这篇文章来讲开地址法的第二种:二次探测再散列(二)、二次探测再散列为改善“堆积”问题,减少为完成搜索所需的平均探查次数,可使用二次探测法。通过某一个散列函数对表项的关键码 x 进行计算,得到桶号,它是一个非负整数。 若设表的长度为TableSize = 23,则在线性探测再散列 举的例子中利用二原创 2013-07-31 17:11:21 · 25692 阅读 · 5 评论 -
散列表(一):散列表概念、 散列函数构造方法、 常见字符串哈希函数(测试冲突)
一、散列表基本概念1、散列表(hash table) ,也叫哈希表,是根据关键码而直接进行访问的数据结构。也就是说,它通过把关键码映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。2、若结构中存在关键码为x的记录,则必定在hash(x)的存储位置上。由此,不需比较便可直接取得所查记录。称这个对应关系hash为散列函数原创 2013-07-30 20:05:42 · 5178 阅读 · 1 评论 -
数据结构:线性表之顺序存储结构
线性表的数据对象集合为 {a1,a2,....an},每个元素的类型均为Datatype。其中,除第一个元素a1外,每一个元素有且只有一个直接前驱元素,除了最后一个元素an外,每一个元素有且只有一个直接后继元素。数据元素之间的关系是一对一的关系。线性表的顺序存储结构的优缺点:优点:无须为表示表中元素之间的逻辑关系而增加额外的存储空间;可以快速地存取表中任一位置的元素O(1)缺点原创 2013-04-20 19:37:37 · 3630 阅读 · 2 评论 -
数据结构:线索二叉树(Threaded Binary Tree)
我们知道满二叉树只是一种特殊的二叉树,大部分二叉树的结点都是不完全存在左右孩子的,即很多指针域没有被充分地利用。另一方面我们在对一棵二叉树做某种次序遍历的时候,得到一串字符序列,遍历过后,我们可以知道结点之间的前驱后继关系,也就是说,我们可以很清楚地知道任意一个结点,它的前驱和后继是哪一个。可是这是建立在已经遍历过的基础之上的。在二叉链表上,我们只能知道每个结点指向其左右孩子结点的地址,而不知道某原创 2013-04-28 19:36:34 · 3605 阅读 · 0 评论 -
数据结构:队列的链式存储结构
队列的链式存储结构,其实就是线性表的单链表,只不过它只能尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头节点,而队尾指针指向终端节点。空队列时,front和rear都指向头节点。示例程序:(改变自《大话数据结构》) C++ Code 12345678910111213原创 2013-04-24 13:40:00 · 2842 阅读 · 0 评论 -
算法:队列与广度优先搜索(迷宫问题)
队列也是一组元素的集合,也提供两种基本操作:Enqueue(入队)将元素添加到队尾,Dequeue(出队)从队头取出元素并返回。就像排队买票一样,先来先服务,先入队的人也是先出队的,这种方式称为FIFO(First In First Out,先进先出),有时候队列本身也被称为FIFO。下面我们用队列解决迷宫问题。程序如下:(参考《linux c 编程一站式学习》) C++原创 2013-04-27 16:54:56 · 10080 阅读 · 4 评论 -
算法:堆栈与深度优先搜索(迷宫问题)
堆栈的访问规则被限制为Push和Pop两种操作,Push(入栈或压栈)向栈顶添加元素,Pop(出栈或弹出)则取出当前栈顶的元素,也就是说,只能访问栈顶元素而不能访问栈中其它元素。现在我们用堆栈解决一个有意思的问题,定义一个二维数组:int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1,原创 2013-04-27 16:26:23 · 10998 阅读 · 1 评论 -
算法:Solutions for the Maximum Subsequence Sum Problem
The maximum subarray problem is the task of finding the contiguous subarray within a one-dimensional array of numbers (containing at least one positive number) which has the largest sum. For examp原创 2013-04-27 11:05:38 · 2052 阅读 · 0 评论 -
数据结构:程序加图示分析单链表的插入和删除操作
下图展示了单链表的基本结构:head指针是链表的头指针,指向第一个节点,每个节点的next指针域指向下一个节点,最后一个节点的next指针域为NULL,在图中用0表示。下面先来看程序(栈的链式存储实现,另外一个实现点这里)和对应的输出(注意输出前进行了链表反转(见《单链表反转》,否则程序后面的while循环输出的顺序是250,200,100),接着来分析程序: C+原创 2013-04-26 20:27:43 · 9723 阅读 · 0 评论 -
数据结构:两栈共享存储空间
数组有两个端点,两个栈有两个栈底,让一个栈的栈底为数组的始端,即下标为0处,另一个栈为栈的末端,即下标为数组长度n-1处。这样,如果两个栈增加元素,就是两端点向中间延伸。当top1 + 1 == top2 的时候为栈满。示例代码:(改编自《大话数据结构》) C++ Code 1234567891011121原创 2013-04-22 22:37:30 · 3767 阅读 · 0 评论 -
数据结构:图的存储结构之邻接表
对于图来说,邻接矩阵是不错的一种图存储结构,但是我们也发现,对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。邻接表的处理方法是这样的。1、图中顶点用一个一维数组存储,另外,对于顶点数组中,每个数据元素还需要存储指向第一个邻接点的指针,以便于查找该顶点的边信息。2、图中原创 2013-04-30 00:05:05 · 144155 阅读 · 26 评论 -
数据结构:图的定义和术语总结
一、图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。在图中的数据元素,我们称之为顶点(Vertex),顶点集合有穷非空。在图中,任意两个顶点之间都可能有关系,顶点之间的逻辑关系用边来表示,边集可以是空的。二、图按照有无方向分为无向图和有向图。无向图由顶点和边组成,有向图由顶点和弧构成。弧有弧尾原创 2013-04-29 13:49:57 · 5708 阅读 · 0 评论 -
数据结构:字符串的基本操作
字符串(string)是由0个或多个字符组成的有限序列。一般使用顺序存储结构,末尾以'\0'表示结束,但不计入字符串的长度。示例程序:(改编自《大话数据结构》) C++ Code 123456789101112131415161718192021222324原创 2013-04-25 13:36:39 · 5335 阅读 · 0 评论 -
算法:求解AOE网的关键路径
前面我们简要地介绍了AOE网和关键路径的一些概念,本文接着对求解关键路径程序的主要函数进行分析。现有一AOE网图如图7-9-4所示,我们使用邻接表存储结构,注意与拓扑排序时邻接表结构不同的地方在于,这里弧表结点增加了weight域,用来存储弧的权值。求解事件的最早发生时间etv的过程,就是我们从头至尾找拓扑序列的过程,因此在求关键路径之前,需要先调用一次拓扑序列算法的代码来计算etv原创 2013-05-02 20:35:03 · 11925 阅读 · 0 评论 -
算法:AOE网(Activity On edge Network)与关键路径简介
前面我们说过的拓扑排序主要是为解决一个工程能否顺序进行的问题,但有时我们还需要解决工程完成需要的最短时间问题。如果我们要对一个流程图获得最短时间,就必须要分析它们的拓扑关系,并且找到当中最关键的流程,这个流程的时间就是最短时间。在前面讲了AOV网的基础上,来介绍一个新的概念。在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的原创 2013-05-02 20:34:06 · 12376 阅读 · 1 评论 -
算法:最短路径之弗洛伊德(Floyd)算法
为了能讲明白弗洛伊德(Floyd)算法的主要思想,我们先来看最简单的案例。图7-7-12的左图是一个简单的3个顶点的连通网图。我们先定义两个二维数组D[3][3]和P[3][3], D代表顶点与顶点的最短路径权值和的矩阵。P代表对应顶点的最短路径的前驱矩阵。在未分析任何顶点之前,我们将D命名为D(-1),其实它就是初始图的邻接矩阵。将P命名为P(-1), 初始化为图中的矩阵。首先我原创 2013-05-01 18:53:58 · 23324 阅读 · 3 评论 -
算法:最短路径之迪杰斯特拉(Dijkstra)算法
对于网图来说,最短路径,是指两顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点为源点,最后一个顶点为终点。最短路径的算法主要有迪杰斯特拉(Dijkstra)算法和弗洛伊德(Floyd)算法。本文先来讲第一种,从某个源点到其余各顶点的最短路径问题。这是一个按路径长度递增的次序产生最短路径的算法,它的大致思路是这样的。比如说要求图7-7-3中顶点v0到v1的最短路径,显然就是原创 2013-05-01 13:32:14 · 11752 阅读 · 3 评论 -
算法:图解最小生成树之克鲁斯卡尔(Kruskal)算法
我们在前面讲过的《克里姆算法》是以某个顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树的。同样的思路,我们也可以直接就以边为目标去构建,因为权值为边上,直接找最小权值的边来构建生成树也是很自然的想法,只不过构建时要考虑是否会形成环而已,此时我们就用到了图的存储结构中的边集数组结构,如图7-6-7假设现在我们已经通过邻接矩阵得到了边集数组edges并按权值从小到大排列如上图原创 2013-04-30 21:33:04 · 16188 阅读 · 4 评论 -
数据结构:栈的链式存储结构
当单链表限定只能在头部进行插入和删除操作的时候,即为链栈,一般我们会将单链表的头指针和栈的栈顶指针top合二为一,通常对链栈来说,是不需要头节点的,因为我们维护了栈顶指针。对于链栈来说,基本不存在栈满的情况,除非内存已经没有可以使用的空间,对于空栈来说,链表原定义是头指针指向空,那么链栈的空其实就是top = = NULL的时候。示例代码:(改编自《大话数据结构》)原创 2013-04-23 17:03:56 · 3372 阅读 · 2 评论 -
数据结构:图的存储结构之邻接矩阵
图的邻接矩阵(Adjacency Matrix)存储方式是用两个数组来表示图。一个一维的数组存储图中顶点信息,一个二维数组(称为邻接矩阵)存储图中的边或弧的信息。设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为:我们来看一个实例,图7-4-2的左图就是一个无向图。我们再来看一个有向图样例,如图7-4-3所示的左图。在图的术语中,我们提到了网的概念,也就原创 2013-04-30 00:03:26 · 90705 阅读 · 12 评论 -
数据结构:静态链表
首先我们让数组的元素都是由两个数据域组成,data和cur。也就是说,数组的每一个下标都对应一个data和一个cur。数据域data用来存放数据元素,也就是通常我们要处理的数据;而游标cur相当于单链表中的next指针,存放该元素的后继在数组中的下标。我们把这种用数组描述的链表叫做静态链表。数组的第一个元素,即下标为0的元素的cur就存放备用链表的第一个结点的下标;而数组的最后一个元素原创 2013-04-22 00:03:53 · 12822 阅读 · 21 评论