
算法导论
文章平均质量分 54
算法导论我去
我喜欢写代码^-^
展开
-
B树相关操作
花了一个下午把书上的B树操作看明白了,又花了一天把代码憋出来…主要是操作比较复杂,需要注意的细节太多…至于删除操作,书上已经详细说明了过程…累啊 有一个不确定的地方是,不清楚如果重复数据有或者比较多的情况会怎么样输入样例21F S Q K C L H T V W M R N P A B X Y D Z E 2M T#include<stdio.h>#include<stdlib.h>#原创 2016-04-20 12:25:23 · 445 阅读 · 0 评论 -
树的直径
问题描述 给定一个公司的网络,由n台交换机和m台终端电脑组成,交换机与交换机、交换机与电脑之间使用网络连接。交换机按层级设置,编号为1的交换机为根交换机,层级为1。其他的交换机都连接到一台比自己上一层的交换机上,其层级为对应交换机的层级加1。所有的终端电脑都直接连接到交换机上。 当信息在电脑、交换机之间传递时,每一步只能通过自己传递到自己所连接的另一台电脑或交换机。请问,电脑与电脑之间传递消原创 2016-04-08 00:38:57 · 260 阅读 · 0 评论 -
(p226)最长单调递增子序列
实际上这应当是贪心算法,d[k]表示[0..i]中长度为k的子串中末尾最小的子串的末尾,因为选择末尾最小的子串,x[i+1]连接到他后面更容易一些,那么,为了让d[k]尽可能小,就要让d[k-1]尽可能小。。。。依次类推,于是需要将小一点的数取代前面的数,以保证后面的可以最小。d[k]是不减的,因此可以用二分查找。具体请看:http://blog.youkuaiyun.com/zsc09_leaf/art原创 2016-03-25 17:26:29 · 288 阅读 · 0 评论 -
(p226)最长单调递增子序列
#include#define max 100int LS(int a[],int f[],int d[],int next[],int n){ int i,j; f[0]=1; for (i=1;i<n;i++) f[i]=0;//初始化值<=1都可以 d[0]=0; for (i=0;i<n;i++) { for (j=0;j<i;j++) if (a[i]>=原创 2016-03-25 14:28:45 · 283 阅读 · 0 评论 -
(p226)最长公共子序列
#include#include#include#define max 100const char lu[4]={0xe2,0x86,0x96},u[4]={0xe2,0x86,0x91},l[4]={0xe2,0x86,0x90};int LCS_LENGTH(char x[],char y[],int c[][max+1],int b[][max+1],int m,int n){原创 2016-03-25 09:07:04 · 303 阅读 · 0 评论 -
(p171)基数树
思路很简单,把浅深色的节点设为1,其余的设为0,先序遍历用s存储当前路径对应的字符串,遇到1输出即可#include#include#include#define max 100struct node{ int f; struct node *l,*r;};void insert(struct node *root,char s[],int dep){ struct nod原创 2016-02-28 18:28:11 · 416 阅读 · 0 评论 -
(p169)构建二叉搜索树和进行相应的操作
#include#include#include#define max 10struct node{ int n; struct node *p,*l,*r;};void randomize(int n[],int size)/*将数组元素打乱*/{ int i,tmp; time_t t; srand((unsigned int)time(&t)); for (i=0;原创 2016-02-28 14:37:16 · 308 阅读 · 0 评论 -
(p138)非递归完成二叉树的遍历
花了将近一个星期才搞懂了非递归遍历的方式,其中后序遍历真心麻烦,具体参考百度百科后序遍历和http://blog.youkuaiyun.com/cqnuztq/article/details/8896953/* * source.c * * Created on: Feb 25, 2016 * Author: wing */#include#include#define m转载 2016-02-25 19:32:49 · 273 阅读 · 0 评论 -
(p138)只用固定量额外存储空间不用递归遍历二叉树
我写过最搞笑的程序:基本思路就是记录从哪个方向到达节点,很多都是复制粘贴^-^/* * source.c * * Created on: Feb 25, 2016 * Author: wing *//* * source.c * * Created on: Feb 25, 2016 * Author: wing */#include#inclu原创 2016-02-25 20:57:36 · 419 阅读 · 0 评论 -
(p143)11.1-4大数组直接寻址
首先,直接访问的肯定是大数组,因此选择在大数组(h)里存元素在栈(st类似于栈)中的位置(如果有的话),注意h应该要是unsigned int类型的,不然有可能为负数,引起数组越界访问错误/* * source.c * * Created on: Feb 24, 2016 * Author: wing */#include#include#define maxn 1原创 2016-02-24 19:20:51 · 568 阅读 · 0 评论 -
(p231)15.5-4最优二叉搜索树(n^2和n^3)
对于长度为l的所有子数组的root[i+1][j]-root[i][j-1]+1的和其实就是root[n-l+1][n]-root[1][l]+n-l=o(n),所以两层循环就是n^2,但是并不知道Knuth的结论是怎么来的,希望知道的分享一下^-^/*attention if max set to 1000 will cause segmentation fault*/#include#原创 2016-03-26 17:55:19 · 670 阅读 · 0 评论 -
p367最小生成树kruskal
kruskal算法(没有生成树结构),利用了22章的不相交森林的操作原创 2016-04-08 16:09:03 · 405 阅读 · 0 评论 -
(p241)活动选择
#include#include#define max 1000int GreedyActivitySelector(int s[],int f[],int ans[],int n)//贪心{ int k=0,i,count=0; for (i=1;i<=n;i++) if (s[i]>=f[k]) { ans[count++]=i; k=i; } retur原创 2016-03-27 09:37:41 · 287 阅读 · 0 评论 -
p549扩展欧几里得
#include<stdio.h>int euclid(int a,int b,int *x,int *y){ if (b==0) { *x=1; *y=0; return a; } else { int d; d=euclid(b,a%b,x,y); int原创 2016-04-16 15:05:52 · 475 阅读 · 0 评论 -
32.3-5带有通配符的匹配(自动机)
功能这个程序可以判断一个带有通配符*的模式串是否在文本串中存在,没有记录位置信息,当然,想记录也是可以的样例输入:abccbacbababcab*bab*c样例输出:1思路对于样例输入,有限自动机如图所示: 我们把每个通配符隔开的字串看做独立的,在其上运行KMP算法的comput_suffix_function过程,区别仅在于每部分的开头的fail指向上部分的结尾,每个部分的结尾fai原创 2016-04-15 18:50:34 · 951 阅读 · 0 评论 -
KMP算法
这是书上的普通版本: 引入π’的原因在于,有时候用π函数跳转多次,多次后面接的字符都是一样的,这就没有必要了,π2保证没两次跳转后面接的字符不一样,从而节省匹配过程的时间,不过计算跳转函数会多一些时间,实际优化效果应该要视输入而定#include<stdio.h>#include<string.h>#define maxn 1000#define maxm 100int f[maxm+1]原创 2016-04-14 21:49:48 · 276 阅读 · 0 评论 -
p587有限自动机
这是书上的普通版本:#include<stdio.h>#include<string.h>#define maxn 1000#define maxm 100int f[maxm+1][26];int is_suffix(char p[],int k,int q,char a){ int i; if (k==0) return 1; if (p[k-原创 2016-04-14 21:44:21 · 394 阅读 · 0 评论 -
32.3-4AC自动机
不知道这是不是题目说的自动机…不过AC自动机还是很有必要了解的 自动机…确实像一个机器,它的状态是有限的,会根据当前的状态和输入转换到另一种状态…原谅我不禁想起了高中生物书上的核糖体做氨基酸链的过程…其实还是有一点像的对吧~~ 学习AC自动机算法,首先应该看看32.3和32.4节(两节都非常有启示性),总而言之,这个算法几乎就是两者的混合 欲要详细的解说:请看 AC自动机算法简单介绍(看了之原创 2016-04-14 21:38:10 · 269 阅读 · 0 评论 -
p(343)通用汇点
i\j 0 1 2 3 4 0 0 0 1 0 1 1 0 0 1 0 0 2 0 0 0 0 0 3 0 0 1 0 0 4 0 0 1 0 0这个算法的运行时间是O(V) - 首先,a[i][i]=0,因此算法走过的路径都在主对角线及以上 - 若a[i]原创 2016-03-29 09:09:30 · 548 阅读 · 0 评论 -
p(247)赫夫曼编码
算法主要在做的事就是从堆中取出两个元素合并成一个新元素,再插入堆中,同时构建二叉树注意堆中要存下二叉树元素的地址,方便引用#include<stdio.h>#include<stdlib.h>struct node{ int f; struct node *l,*r;};struct heap{ int f; struct node *hnode;};in原创 2016-03-28 17:42:06 · 332 阅读 · 0 评论 -
(p245)分数背包(O(n))
思路请参考:http://blog.youkuaiyun.com/mishifangxiangdefeng/article/details/7748435写起来还是挺麻烦的复杂度为On的原因主要就是1+1/2+1/4+1/8....=2#include#include#define max 1000float v[max+1]={0,60,100,120};int w[max+1]={0,原创 2016-03-27 17:14:40 · 922 阅读 · 0 评论 -
(p244)01背包问题
#include#define maxn 100#define maxw 1000int w[maxn+1]={0,10,20,30},v[maxn+1]={0,60,100,120},d[maxn+1][maxw+2],n=3,W=50,ans;//现在才知道大数组要声明为全局变量才不会报错int select(int w[],int v[],int n,int W){ int i,原创 2016-03-27 14:24:59 · 263 阅读 · 0 评论 -
p357强连通分量
书上的这个算法叫做kosaraju算法首先做一次dfs计算图的转置在转置图上按照第一次dfs完成时间f递减的顺序再进行一次dfs 前两个步骤很直白,关键是第3步,要按递减的顺序嘛,于是我就想排序,拍完后发现不对,由于点在g数组的位置发生了变化,整个图的结构完全被打乱了→_→;其实我忽略了dfs非常重要的性质——这不是有一个时间戳嘛?节点探索完成的顺序就是f递增的顺序,放到头插法创建的链表里面原创 2016-04-01 11:31:28 · 446 阅读 · 0 评论 -
22.4-5拓扑排序BFS
这个问题和宽度优先搜索很相似,是横向扩展入度为0的节点队列中都是入度为0的元素,将一个元素出队列之前,将与他相连的元素的入度减1,如果为0将新元素入队列#include<stdio.h>#include<stdlib.h>typedef struct edge{ int i; struct edge *next;}edge;typedef struct node{原创 2016-03-31 18:54:58 · 311 阅读 · 0 评论 -
(p124)k分位数
首先,这个题意思应该是:对一个包含n个元素的集合来说,k分位数是指能把有序集合分成k个等大小集合的k-1个顺序统计量,给出一个能找出某一集合的k分位数的O(nlgk)算法——书上多印了一个“第”字,搞得莫名其妙-_-; 好吧,既然清楚了,我们来分析以下复杂度,lgk——这说明很有可能要用到分治,再根据递归树模型,我们就可以看出来,大概有这样一个函数:find(int *num,int k,i原创 2016-02-16 21:28:07 · 2218 阅读 · 0 评论 -
(p123)最坏情况为线性时间的选择算法
/* * select.c * * Created on: Feb 16, 2016 * Author: wing */#include#include#includeint sort(int *num,int l,int r){ int i,j,x; for (i=l+1;i<=r;i++) { x=num[i]; j=i-1; while(j>=原创 2016-02-16 17:01:04 · 420 阅读 · 0 评论 -
(p120)线性时间找到顺序统计量
/* * find.c * * Created on: Feb 15, 2016 * Author: wing */#include#include#includeint exchange(int *num,int i,int j){ int tmp; tmp=num[i]; num[i]=num[j]; num[j]=tmp; return 0;}i原创 2016-02-15 21:31:22 · 442 阅读 · 0 评论 -
(p112)在O(n)时间内,对0到n^3-1区间内的n个整数进行排序
/* * sort.c * * Created on: Feb 15, 2016 * Author: wing */#include#include#includestruct num{ int n; int d[3];};int digitsort(struct num *x,int j,int n,struct num *result){ int i,原创 2016-02-15 17:40:21 · 2318 阅读 · 0 评论 -
(175)红黑树及其相关操作
不得不说,红黑树虽然有点难懂,有点麻烦,但这一章的确是非常精彩的一章,看了还想看^-^首先,作者为我们说明了一种思路,定义一种数据结构的基本性质->根据这种结构的基本性质推导它的性能之类的->进行操作时维护这种性质->操作之后仍然满足性质,即具备相应的性能,这种自底而上的思路很有代表性其次,研究本章的算法可以加深我们对于迭代的理解,对于复杂的问题可以从某一时刻入手,研究这一时刻各种可能的状原创 2016-03-02 10:14:04 · 258 阅读 · 0 评论 -
(p111)基数排序(子程序是计数排序)
/* * sort.c * * Created on: Feb 14, 2016 * Author: wing */#include#includeint figk(int n){ int c=0; while (n!=0) { c++; n=n/10; } return c;}int getdigit(int n,int k){ int i原创 2016-02-14 12:14:18 · 458 阅读 · 0 评论 -
(p106)对区间的模糊排序(将相同元素挤在一起的快排)
这里定义区间a/* * sort.c * * Created on: Feb 13, 2016 * Author: wing */#include#includestruct line{ int l; int r;};int exchange(struct line *x,int i,int j){ struct line tmp; tmp=x[i];原创 2016-02-13 23:14:31 · 661 阅读 · 0 评论 -
(p93)k路归并
和归并排序一样,k路稍微复杂一点,用一个最小堆(tmp)维护每个有序数组(result)剩余第一个元素的最小值,添加到结果数组中,由于堆是对指针进行操作,因此没取出一个数,将其指针指向下一个元素即可(为了判断一个数组的元素是否取完,在每个数组后面添加了一个最大值32767),代码如下:/* * sort.c * * Created on: Feb 13, 2016 * Au原创 2016-02-13 23:01:45 · 511 阅读 · 0 评论 -
p39最大子数组问题o(lgn)
/* * max.c * * Created on: Feb 4, 2016 * Author: wing *//* * test.c * * Created on: 2016年1月21日 * Author: wing */#include#includeint smax(int *num,int l,int r,int *maxi,int *m原创 2016-02-10 10:28:07 · 376 阅读 · 0 评论 -
(p125)9.3-8找两个数组元素的中位数
我一开始是想:先在a数组中选择一个数x,再在b数组中找到两个相邻的数,让x夹在它们中间,由此确定x的位置,进而判断是否是中位数,但是找到相邻的数复杂度是O(n)的,无奈,只好作罢-_-后来发现有人是反过来做的,直接根据b中的坐标判断x是大于还是小于中位数,有的时候,真的需要换个角度!!分治算法,需要注意的是递归的终止条件是l>=r而不是l==r,导致stack overflow的原因很转载 2016-02-17 12:06:36 · 347 阅读 · 0 评论 -
(p193)顺序统计数及相关操作
代码和红黑树的基本一样,只是由于多了size属性,需要和color,bh等属性一样,在对其进行操作时需要维护这个属性leftrotate和rightrotate以及insert和delete里面自然要进行维护,这里要说的是,由于维护过程都在前面四个里面操作了,transplant里面并不需要进行维护,另外,尽管delete里面情况较多,实际上还是只需要共用一个维护过程/* * sourc原创 2016-03-03 16:19:34 · 247 阅读 · 0 评论 -
(p196)利用顺序统计树求逆序对
只需要将insert里面的while循环改成下面这个样子就行了,思路是insert的时候,节点每往左移动一次,那么说明它比右边的都要小,所以加上右边的数目,而红黑树的旋转并不会影响 while (next!=t->nil) { prev=next; next=new->nn?next->l:next->r; count=new->nn?count+prev->size-next-原创 2016-03-03 17:16:44 · 361 阅读 · 0 评论 -
(p130)栈和队列
两个程序的功能都是输入0就出栈(出队列),输入1就是入栈(入队列),输入-1结束栈:/* * stack.c * * Created on: Feb 22, 2016 * Author: wing *//* * stack.c * * Created on: Feb 22, 2016 * Author: wing */#include#in原创 2016-02-22 09:21:28 · 220 阅读 · 0 评论 -
(p138)递归完成树的遍历
递归还是很简单的,分分钟写出来,可是非递归那就有点难了,加油加油!下面是递归的代码:/* * source.c * * Created on: Feb 22, 2016 * Author: wing */#include#include#define max 10/*二叉树节点数目*/struct node{ int n; struct node *p,*l,原创 2016-02-23 00:12:51 · 541 阅读 · 1 评论 -
22.4-2简单路径条数
利用有向无环图的性质,不存在后向边,只存在树边前向边和横向边给节点增加一个属性,即节点到目标节点的简单路径条数考虑节点u v是白色的,则v.count还没有计算,计算v.count,再u.count+=v.countv是黑色的,则将u.count+=v.count,避免重复计算,因此具有动态规划性质v不可能是灰色的算法的复杂度和dfs相同为o(v+e)#include<stdio.h>原创 2016-03-31 15:51:45 · 1832 阅读 · 0 评论 -
p354拓扑排序
有向无环图为我们提供了一个非常有用的性质,假设有边(u,v),那么u.f>v.f,不论u,v是不是在同一棵树里面因此,算法将每个节点一经完成就加入列表,使得后插入的节点不可能有边指向先插入的节点,这样就完成了拓扑排序typedef struct link_element{ node *pnode; struct link_element *next;}link_element;原创 2016-03-31 14:05:32 · 277 阅读 · 0 评论