
数据结构与算法
文章平均质量分 79
疯狂的红豆
拥有热情相信未来
展开
-
图结构系列—基于邻接矩阵的图实现
在数据结构中跌跌撞撞的走到了图这个部分,回想在几个星期前还在为各种树的各种结构定义与算法实现苦恼,忽然间已经来到了数据结构中貌似是最重要的一个结构了。在之前就有听说图在各行各业的理论研究上用途很广,如人工智能,寻路,更让我想不到的还有化合物的鉴定......可见图的未知的应用还有多少了。从逻辑上分,图分为有向图与无向图。从存储表示上可以有着重用顶点表示一个图的,当然也有着重用边来表示一个图的。原创 2012-11-27 22:27:53 · 2090 阅读 · 0 评论 -
约瑟夫问题详解
约瑟夫问题记得是在学习C语言数组的时候写过的一道题目,至于什么是约瑟夫问题我想大多数学过C的人都应该知道的,下面就来说下如何利用数组解决约瑟夫问题。默认的约瑟夫问题是从第一个人开始计数,并且留下最后一个幸存者,笔者做的改进是可以从指定位置起始计数,并且可以留下指定的人数,并且可以查看被踢出的人。最开始要求输入总人数,然后指定起始计数位置(默认从第一个开始),剩余人数(默认剩余一个人)。每一个被原创 2013-01-13 12:39:24 · 3162 阅读 · 0 评论 -
基于链式存储结构的栈
基于链式存储结构的栈和单链表几乎没差,不同的地方在链栈也是只能在一端进行存取操作,而单链表则可以在任何位置进行。单链表的建立分为前插法和后插法,前插法是将每次新插入的结点作为头,后插法是将每一次新进入的结点放在最后面。链栈的建立用前插法是很方便的。链栈的结点类和单链表的一样:#pragma once#includeusing namespace std;templateclass原创 2013-01-13 13:18:13 · 1760 阅读 · 0 评论 -
栈的应用—中缀转后缀求表达式值
栈的应用有很多,我们最熟悉的函数调用与递归等对编译器来说都是用栈的工作原理来实现的。还有我们的浏览器中有一个向后退选项,这就是一个栈的应用了(这个是中的举例)。还有就是本篇要讲的表达式求值了。我们知道C/C++是基于表达式的程序设计语言,可见表达式对于语言的重要性了。至于什么是表达式等话题这里就不讨论了,直接说表达式的三种类型,他们分别是:前缀表达式,中缀表达式,后缀表达式。在这里只讲对于双目原创 2013-01-18 23:27:52 · 7464 阅读 · 1 评论 -
队列的应用—电路布线最优解问题
首先什么是电路布线问题呢?电路布线问题是类似于迷宫的问题,也是一个模拟矩阵,迷宫是每个点有8个方向可以走,但是在电路布线问题中每个点上只有上下左右4个方向可走。因为电路布线不允许对角线上布线,并且电路布线问题要求线路所走过的路程必须是最短的,即从出发点到目的点路径很可能有很多,要找的是经过跳数最少的那个。也就是说不能太多的弯儿,能直走的就直着走。迷宫问题是只要找到出路,不管路径是如何的。在寻找原创 2013-02-05 20:39:29 · 4691 阅读 · 1 评论 -
基于链式存储的队列
日常生活中我们吃饭,买票等都是要排队的,这里的排队其实就是对应着数据结构中的队列了。其中排队过程中不允许插队也是一个能反应队列结构性质的表现吧。队列和栈一样,是一个被限制存取的线性结构。普通队列规定只能在队头出,只能在队尾进,这也是为什么不允许插队的原因了。当然这里讨论的是最简单的最普通的队列了,当然还是有一些特殊的队列的,比如双端队列,优先级队列等,后续细说。基于链式存储的队列结构中,结点类原创 2013-01-22 18:34:35 · 1425 阅读 · 0 评论 -
基于数组的循环队列
之前讲的是基于链式存储的队列,如果是基于数组的存储结构 的队列会是怎样的呢?起初队头和队尾均指向第一个元素,随着不断地进队列,后来队列满了。这时候从队头出队列,当出完后此时队头和队尾均指向数组的末尾了。虽然这个数组是空的,但是不能用来存储了,造成了很大的浪费。在这个时候能不能将数组前面的空位置利用起来,继续用来存储呢?这个时候就用到了循环队列的概念了,循环队列主要是为了解决基于顺序存储的队列造成的原创 2013-01-22 19:41:07 · 9154 阅读 · 0 评论 -
最长公共子序列问题
最长公共子序列问题很早就在很多论坛上见过,前几天看到一个人发了一篇帖子,心血来潮就去看算法导论上的动态规划部分,关于这个问题不再细述,直接贴C++实现的具体代码了。//做大公共子序列问题#pragma once#include using std::string;#define OVER 1 //书中使用箭头符号表示的,这里用宏代替#define LEFT 2#define原创 2013-03-05 15:30:06 · 1532 阅读 · 0 评论 -
洗牌算法多种形式
洗牌算法直观的来说,是将一幅有序的扑克牌经过处理后变成乱序的。这个处理的过程就是洗牌算法了,当然这里的扑克牌也许是其他的数据等等,算法要保证乱序后的数据和之前的一模一样,只是顺序不同而已。下面就针对不同形式的洗牌算法给出代码。有54张牌,乱序存储在一个整型数组中arr[54]。一副牌就用1,,,54这54个数字代替。//从无到有随机生成一副牌序void MyShuffle_Non原创 2013-02-24 00:54:23 · 1834 阅读 · 0 评论 -
字符串匹配朴素算法
这个朴素算法的英文命名为BruteForce,暴力的意思,所谓的朴素算法就是算法分析上常讲的暴力求解方法。这是一种方法,也是一种算法思想,就是不考虑空间时间复杂度,以最简单的看待问题的视角去思考,去解决。比如八皇后问题,使用8重循环来依依判断,比如全排列,使用多重循环枚举的方式等等。字符串匹配问题的朴素算法是字符串算法中最基本也可以算是最简单的算法了。他就是按照大多数人们的思维去思考这么一个匹原创 2013-03-10 09:55:26 · 9583 阅读 · 0 评论 -
动态规划——装配线调度问题
这个问题是在算法导论的动态规划章节有提到,由于问题叙述起来太繁杂就直接省略。命名规则与书上的伪代码是一致的,只是用C++具体语言实现了而已。//动态规划问题——装配线调度问题#pragma onceclass ASL{private: int stationNum; //装配站个数,从文件中读取 int *arr1; //装配线1 int *arr2;原创 2013-03-03 23:24:42 · 2051 阅读 · 2 评论 -
字符串匹配算法之KMP算法
这个算法是字符串匹配算法中的佼佼者,仅利用O(lengthText + lengthPattern)的时间就完成了匹配任务。他快速的原因是无须回溯。这个算法最高深的也是最难懂的地方在于,两个串进行匹配,成功与否竟然只和模板串有关系,和目标串是没有关系的。当模板串在j位置匹配失败后,不用重新到0位置,下一次的位置应该再next[j]的位置。下面是生成next数组的函数:void GetNex原创 2013-03-14 00:02:49 · 2249 阅读 · 0 评论 -
基于单链表的多项式问题
上学期的东西了,不想再去细究思路了,直接贴代码,注释很详细#pragma once#includeusing namespace std;class LinkNode{public: float coef;//系数 int expn;//指数 LinkNode *link;//指向后继的指针域 LinkNode *plink;//指向前驱的指针域public: LinkN原创 2013-03-23 23:20:53 · 2706 阅读 · 0 评论 -
二叉树实现详解
二叉树按照数据结构类型来划分属于树结构,在树结构中他又是比较简单而且具有理论研究的意义的一种数据结构。有很多树形结构都是基于二叉树的变种,所以对二叉树的学习与了解是很有必要的。根据笔者的经验,在学习数据结构的过程中要深刻的体会逻辑接口与物理存储实现的区别与联系。比如在之前的博客中有讲到栈和队列的实现,栈和队列都有基于数组存储方式的实现和基于链表存储形式的实现。所谓的逻辑接口就是这个数据结构具备哪些原创 2013-05-01 18:48:04 · 14574 阅读 · 2 评论 -
队列的应用—输出杨辉三角
#include"Queue.h"#includeusing namespace std;const int total_row = 6;void main(){ void Pascal_Triangle();//函数声明 Pascal_Triangle();}void Pascal_Triangle()//杨辉三角 输出二项式系数{ Queue qu;//队列 int e原创 2013-01-26 23:08:41 · 6919 阅读 · 0 评论 -
基于顺序存储结构的栈
栈也是一种线性结构,如果用一句话介绍栈的话,那就是后进先出(LIFO:Last In First Out)。栈的特性是由于其特殊的存取方式决定的,那就是只能在一端进行存取动作。可以存取的一端一般称为栈顶,另一端称为栈底。究竟栈底索引置为-1还是置为0也是一个讲究,普遍的方法是置为-1,这一点在后面的存取操作中会发现优势。 一般有push和pop操作,以及栈空,栈满等判断。本文介绍的是基于顺序存原创 2013-01-13 13:09:56 · 1524 阅读 · 0 评论 -
基本单链表实现
这个学期初识数据结构,不知其为何物,更不知道其在软件工程以及计算机科学中的重要地位与作用。在这个学期的第一个月内我只做了一件事,那就是认真的读教材,认真的分析书上的所有代码,慢慢的我也懂了什么是数据结构了,并在看书的过程中不断的思考为什么要这么做,中途也会自己冒出一些想法来。因为教材有不完善或是错误的地方(后续的结构中会在代码中提示出来),而且确实诟病很多,所以我就在看懂一个结构后对他修修改改使结原创 2013-01-10 10:36:46 · 2112 阅读 · 0 评论 -
图结构系列—基于邻接表的图实现
上一文中介绍了基于邻接矩阵的图实现,介绍了一些邻接矩阵的一些表示优势。下面来说一下基于邻接表的描述无向图的具体实现,在实现前有一些结点类型说明一下:首先是边信息类型:#pragma once#includeusing namespace std;templateclass EdgeNode{public: int dest; //该边的对称顶点在NodeTable中的索引值原创 2012-11-27 22:53:23 · 2158 阅读 · 0 评论 -
图结构系列—图的遍历
对于图的描述,已经把最基本的结构定义以及操作算法说的差不多了,其余的当做补充在后序中说吧。一个图,不管是有向的无向的,是基于什么结构存储的,这些差异都体现在存储上,对于上层的业务逻辑来说,都是一样的。所以现在来讨论一下有关图的遍历算法的实现。图的遍历有深度优先算法,以及广度优先遍历算法。我们作为教材学习的是着重于 顶点描述一个图,所以对图的遍历也是针对顶点的搜索与判断,查询等。之前学的树原创 2012-11-29 21:57:13 · 1157 阅读 · 0 评论 -
并查集的实现
之前没有接触过集合这种数据结构,而且还因为课程进度慢的原因就没讲,但是最近在学最小生成树的算法的时候用到了并查集这个结构。但是没学,那天和老师聊的时候,受命写了一个并查集的数据结构供大家使用。我写之前只是看了看百度的对并查集的描述和Kruskal算法的需求,就开始动手写了,因为这个学期因为数据结构喜欢上了GP编程,并通过不断的学习结构定义与算法实现,自己为了锻炼一下子,就采用了模板,而且这个并查集原创 2012-12-02 23:48:02 · 1569 阅读 · 0 评论 -
最小生成树之Prim算法的实现
这个算法的实现与克鲁斯卡尔算法的实现,个人感觉思想还是差很多的。K算法从第一个迭代就保证了符合最小生成树的基础上的算法正确性,因为每一次选的都是符合规则的前提下代价最小的。然而P算法却不是这么想的,当初上课的时候还问老师,如何证明P算法的正确性。最后发现,不管首次选取的是哪一个点,都是找与此点相关联的边中代价最小的,所以经过某些轮的迭代(最后是图的边数目次)就会把所有权值中最小的那个加进去,倒数第原创 2012-12-03 00:09:09 · 1836 阅读 · 0 评论 -
最小生成树之Kruskal算法的实现
克鲁斯卡尔算法定义:(百度贴来的) 假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两原创 2012-12-03 00:00:05 · 1801 阅读 · 0 评论 -
Dijkstra最短路径算法(SPF)
算法描述:Dijkstra算法是一种求单源最短路的算法,即从一个点开始到所有其他点的最短路。其基本原理是:每次新扩展一个距离最短的点,更新与其相邻的点的距离。当所有边权都为正时,由于不会存在一个距离更短的没扩展过的点,所以这个点的距离永远不会再被改变,因而保证了算法的正确性。不过根据这个原理,用Dijkstra求最短路的图不能有负权边,因为扩展到负权边的时候会产生更短的距离,有可能就破坏了原创 2012-12-04 22:42:53 · 15258 阅读 · 1 评论 -
AOV网络
在现代化管理中,人们常用有向图来描述和分析一项工程的计划和实施过程,一个工程常被分为多个小的子工程,这些子工程被称为活动(Activity),在有向图中若以顶点表示活动,有向边表示活动之间的先后关系,这样的图简称为AOV网。如下图是计算机专业课程之间的先后关系: 图片注释:基础知识课程应先于其它所有课程,pascal语言课程应先于数据结构。 用顶点表示活动,用弧表示活动原创 2012-12-06 19:19:19 · 2001 阅读 · 0 评论 -
哈夫曼树详解
一:什么是哈夫曼树呢?来看一下百度给的定义吧:给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman tree)。PS:哈夫曼树是在二叉树的基础上定义的。自己的描述:在树的路径长度的基础上引入了带权路径长度(Weighted Path Length,WPL)。一棵叶子结点带权值(分支节点不带权值)的二叉树叫做扩充二叉原创 2012-11-24 13:47:38 · 2418 阅读 · 0 评论 -
哈夫曼树详解<续>
上面介绍到最小堆的模板实现以及模板的使用情况,这篇中就如何构造 一个哈夫曼树的核心算法思想作介绍。一棵哈夫曼树的结点有带不带权值之分,也就是内外结点之分,所以在这里用了一个枚举类型enum_modes,标示内外结点的。在构造哈夫曼树(HuffmanTree)时,定义了一个最小堆,类型就是哈夫曼树结点(HuffmanTreeNode)类型。下面贴源码:首先是枚举类型:#pra原创 2012-11-24 14:10:17 · 3006 阅读 · 1 评论 -
双向链表的实现
单链表是最基本最简单的结构了,用处也蛮多的吧,尤其是后面在层序结构的各种树与图结构的时候大量使用链表而且还很多是单链表形式的。学习双向链表还是由约瑟夫问题引入的呢,在单链表的删除操作时需要用并排的两个指针同步向后移动,为避免这个问题双向链表就派上用场了。双向链表顾名思义是每个结点有两个方向了,那么在结点里面不仅仅要保存一个后向指针还要保存一个前向指针了。#pragma once#includ原创 2013-01-10 10:54:06 · 2646 阅读 · 0 评论 -
基于栈操作的迷宫问题求解
新的一年的第一个月都已经过了一个星期了,发现这个月至今还没有写一篇博客呢,于是就把之前学栈的时候写过的一个基于栈操作的迷宫问题求解给贴上来吧,哈哈哈。。。。迷宫的描述:用一个二维数组表示一个迷宫,这个二维数组的每一个元素的上下左右以及对角线上的四个方向,这总共加起来是八个方向,其中数字0表示可以通过,数字1表示此处不通,判断给定的一个迷宫是否有出路,有出路的话,求解出走出的路线。存储结原创 2013-01-07 13:45:13 · 6932 阅读 · 4 评论 -
双向循环链表的实现
在使用链表来解决约瑟夫问题的时候,用到了循环链表。循环链表又分为单向循环链表与双向循环链表,约瑟夫问题采用单向循环链表可以得到很好的而解决了,但是单向链表的很大的缺陷仍然存在,那就是在删除的时候需要两个并排指针同步移动。双向链表就可以解决这个问题,因为在双向链表中的每一个结点都有两个指针域来分别指向其前驱和后继。这样子在遍历链表时不用两个指针,直接使用一个就好,当锁定位置后,取出其前驱然后再保存当原创 2013-01-10 12:16:17 · 2715 阅读 · 3 评论 -
递归求解迷宫问题
前面已经介绍了迷宫的存储等一些准备工作,这篇博客就只是介绍利用递归思想解决迷宫问题。递归有几个要义:知道在函数的哪里调用自身进行递归,换句话说就是递归的条件是什么,然后递归的出口是什么。最开始当前位置记录的是起始位置,然后利用循环有顺序的去判断8各分支是否可走,如果可以那么就将这下一个位置的行和列传入函数本身,进行递归了。如果下一个位置不行,那么在跳转在下一个方向,还有就是如果一个位置上8个方原创 2013-01-07 14:33:03 · 4553 阅读 · 1 评论 -
基于循环链表的约瑟夫问题
#pragma once#includeusing namespace std;templateclass LinkNode //一个结构体对外全部可见{public: T data; //模板类型的一个数据 LinkNode* link; //该struct的一个指针,用于指向下一个结点public: LinkNode(LinkNode* ptr = NULL)//只初始化指原创 2013-05-30 19:43:39 · 1950 阅读 · 0 评论