算法
文章平均质量分 82
YetToCome
这个作者很懒,什么都没留下…
展开
-
栈和队列
栈:先进后出的动态结构,也就是说可以去掉的元素是最近插入的那一个用一个数组S[1..n]实现一个至多有n个元素的栈,top[S]指向最近插入的元素,S[1]表示栈底元素,S[top[S]]表示栈顶元素,如下图所示:以下是栈所支持的操作://该代码不考虑栈的溢出情况,使用int数组实现#include #include //假设栈所支持的元素最大个数是10个#de原创 2013-07-13 17:44:16 · 670 阅读 · 0 评论 -
Dijkstra in python
下面是一段由python实现的Dijkstra算法,一些地方的处理实在非常棒,相比于C,代码的数量已经缩减到了60行,所以我想通过本文原创 2013-10-10 20:29:39 · 1660 阅读 · 0 评论 -
动态规划概述
在之前http://blog.csdn.net/yettocome/article/details/9840539问题上,原创 2013-08-11 16:19:49 · 1564 阅读 · 0 评论 -
动态规划之 矩阵链乘法
承接着上一篇的装配线调度问题,下一个要解决的问题是矩阵链乘法问题:给定n个要相乘的矩阵构成序列,原创 2013-08-10 12:54:27 · 3033 阅读 · 0 评论 -
动态规划之 装配线调度问题
从之前提到的最长公共子序列的问题中已经可以看到动态规划的应用之处,但是对于这种算法,或者说是一种思想,该在什么地方使用,哪些问题的解决可以使用动态规划,可能并不清晰。下文所讲述的内容就是可用动态规划解决问题的两个要素:最优子结构和重叠子问题。在分析这两个要素之前,先以两个例子引入:装配线调度假设一个汽车底盘加工有两个装配线,如下如所示,每个装配线都有n个配件站,用于给底盘安装不同的零件原创 2013-08-08 15:47:39 · 8048 阅读 · 1 评论 -
最长公共子序列(LCS问题)
先简单介绍下什么是最长公共子序列问题,其实问题很直白,假设两个序列X,Y,X的值是ACBDDCB,Y的值是BBDC,那么XY的最长公共子序列就是BDC。这里解决的问题就是需要一种算法可以快速的计算出这个最大的子序列,当然,用最简单的方法就是列出XY全部的子系列然后一个个对比,但这样的时间复杂度是绝对不能接受的。假设X的长度是m,Y的长度是n,拿X的一个子序列和Y进行对比的时间是n,计算X的全部子序原创 2013-08-06 20:51:47 · 4356 阅读 · 1 评论 -
动态顺序统计
在之前的随机选择算法中,我们可以很快的在集合中寻找到第i小的元素,然而,这样的集合并不支持动态的扩充。这一节里,将介绍通过红黑树(具体可参考红黑树1,红黑树2两篇文章)的扩充,使得任意的顺序统计量都可以在短时间内查找到,而这样的数据结构同时也支持数据的更新。这样的数据结构称为顺序统计树,如下图。树的节点大致上与红黑树的类似,但增加了一个记录子树大小的域size[x],定义哨兵Nil的子树大小为原创 2013-07-19 16:57:54 · 1590 阅读 · 0 评论 -
红黑树(删除操作)
上一篇文章主要讲到了红黑树的基本性质以及插入节点的操作,有了上面的基础后,今天就把红黑树剩余的一个难点也就是删除节点的操作详细的讲一下。红黑树节点的删除方法一开始的操作和二叉搜索树差不多,都是首先判断需要删除的节点,分为三种情况,一是如果这个节点没有子女的话,那么直接修改父节点的值,断开他们之间的关系即可。如果这个节点只有一个子女,那么修改它的父节点,使父节点直接连接其子节点。如果该节点有两个原创 2013-07-18 13:03:04 · 1716 阅读 · 1 评论 -
红黑树(基本性质及插入操作)
从二叉查找树中我们可以看到,一些基本的动态操作如查询,求后继、前驱,插入,删除等,其时间复杂度都与树的高度有关,当树的高度较低,也就是二叉树比较平衡的时候,这些操作执行的就会很快;但当树的高度较高时,例如每次向二叉树插入节点都一直向右,那么将会造成树的不平衡,这样的操作还不如直接使用链表方便。而为了保证树的平衡,这里就引入了红黑树的概念,他保证在最坏的情况下,树的高度总是log(n)。1.红黑原创 2013-07-17 17:08:26 · 1822 阅读 · 2 评论 -
二叉查找树
二叉查找树是按二叉树的结构组织的,节点用链表表示,除了表示数据的key域和一些卫星数据外,还包含域left,right和p,分别指向左孩子,右孩子和父节点。如果孩子节点或者父节点不存在,那就用NULL表示。根节点是树中唯一一个父节点为NULL的节点。那么,二叉查找树满足什么性质呢?其实就一句话,左孩子的值总是不大于父节点的值,右孩子的值总是不小于父节点的值。为了将二叉树中的值按照顺序输原创 2013-07-16 12:20:39 · 1166 阅读 · 0 评论 -
计数排序(BitMap实现)
计数排序:计数排序假设n个输入元素中的每一个都是介于0到k之间的整数,对每一个输入元素x,确定出小于x的元素的个数,就可以把x直接放到最终输出数组的位置上。例如有17个元素小于x,那么x位于第18个输出位置。而当有几个元素相同时,方案需要修改,不能把他们放在同一个输出位置上。也就是说,计数排序比较适合元素之间没有重复的情况。就时间效率来看,计数排序几乎是只需要扫描一遍数组就可以将数原创 2013-07-15 15:43:33 · 1280 阅读 · 0 评论 -
快速排序
和归并排序一样,快速排序也是基于分治法的。下面是对一个典型的子数组A[p..r]排序的分治过程的步骤:1.分解:将数组数组A[p..r]划分成两个(可能为空)子数组A[p..q-1]和A[q+1..r],使得A[p..q-1]中的每一个元素都小于A(q),且A[q+1..r]大于等于元素A(q)。总之,就是以A[q]为分界点进行划分,具体的步骤稍后说明。2.解决:通过递归调用快速排序算法,原创 2013-07-15 13:41:21 · 745 阅读 · 0 评论 -
随机选择算法
之所以需要随机选择算法,是为了克服一般查找时的从左向右一个个查找的缺点,其思想非常类似于快速排序,还记得快排第一步是干什么吗?就是分割原数组,分割的那个点其实在数组中已经“归位”了,就是摆放在了正确的位置上,分割点左边的元素都是小于它,而右边的都大于它。随机选择算法就是利用了这一点,每次分割完后,算法就查找分割点是不是要找的那个数,如果是的话,那就直接返回,如果要找的比分割点大的话,那就在分割原创 2013-07-15 16:49:31 · 1200 阅读 · 0 评论 -
优先级队列(大顶堆实现)
使用大顶堆可以高效的实现优先级队列,具体大顶堆的用法,可参考:堆排序优先级队列是用来维护一组元素构成的集合S 的数据结构,每一个元素都含有一个关键字key。一个最大优先级队列支持一下操作:Insert(S,x):把元素x插入到队列中,与一般队列不同的是,优先级队列入队的操作总和队列中已有的元素进行比较,找到适当的位置进行插入,本例中,入队的操作总是能使优先级队列保持有序状态。Maxim原创 2013-07-14 16:11:46 · 2191 阅读 · 1 评论 -
堆排序
堆:可以被视为一个完全二叉树,树的每一层都是填满的,除最后一层外。表示堆的数组A具有两个属性:length[A]是数组中元素的个数,heap_size[A]是存放在A中的堆的元素的个数。就是说,A[heap_size[A]]之后的元素都不属于相应的堆,heap_size[A]length[A]。树的根为A[1],给定节点下标,可以很快算出它的父节点,左孩子和右孩子节点。PARENT(i)=i/原创 2013-07-14 15:00:39 · 963 阅读 · 0 评论 -
归并排序
在介绍归并排序之前,首先需要介绍一下分治法的思想很多算法在结构上是递归的,算法需要一次或多次调用自身来解决相应的子问题,即将原问题划分成n个规模较小而结构与原问题相似的子问题,递归的解决这些子问题,然后合并其结果,就得到原问题的解。分解:将原问题分解为一系列子问题解决:递归解决各个子问题。若子问题足够小,则直接解决合并:将子问题结果合并成原问题的解。归并排序其实就是应用原创 2013-07-14 13:39:13 · 1022 阅读 · 0 评论 -
插入排序
插入排序是对少量元素进行排序的有效算法。其工作原理与打牌类似,开始摸牌时,我们的左手是空的,一次从桌上摸起一张牌,插入到左手牌中正确的位置上。为了找到这个正确的位置,需要将它与手中已有的每一张牌从右到左进行比较。无论什么时候,左手的牌总是已经排好序的。具体的方法是通过一个数组A[1..n],包含了n个待排序的数,这些数组在数组A中就地排序,不需要添加额外的空间。以下是代码:原创 2013-07-14 09:52:06 · 700 阅读 · 0 评论 -
链表
链表:顺序由各对象的指针决定,可以灵活的表示动态集合,但效率不及数组高,形式如下图所示:next[x]指向链表中x的下一个元素,prev[x]指向上一个元素,head[L]指向第一个元素,若head[L]=NULL,则该链表为空。程序中使用的是双向链表。#include #include //链表中的每一个元素,包含一个值x,一个指向前驱的指针prev以及指向后继的指原创 2013-07-13 20:18:58 · 735 阅读 · 0 评论 -
穷竭搜索
穷极搜索主要包括两个方面:1.深度优先搜索2.广度优先搜索一些基本的思想1.递归函数在函数中调用自己的函数就是递归函数,例如阶乘函数可以定义为:int fact(int n){if (n == 0) return 1;return n * fact(n - 1);}递归最重要的一点就是函数的停止条件,在上面的例子中,当传入的参原创 2013-11-20 20:06:15 · 1296 阅读 · 0 评论