算法导论-CLRS
文章平均质量分 56
weishenmetlc
这个作者很懒,什么都没留下…
展开
-
第12章:二叉搜索树部分答案:
12.1-2:在二叉搜索树中,一个结点的关键字要大于等于其左孩子的关键字,小于等于其右孩子的关键字。但在最小堆中,结点的关键字只要小于等于其左右孩子的关键字即可。不可以。因为在最小堆中,它只告诉你结点的关键字要小于其左右孩子的关键字,但并没有告诉你左右孩子结点的关键字谁大,因此无法像二叉查找树那样,按序输出元素。再说,如果最小堆能够在的时间O(n)O(n)的时间内按序输出一个元素,又由于最小堆的原创 2016-03-06 14:29:29 · 617 阅读 · 0 评论 -
第8章:线性时间排序
一:计数排序:计数排序假设n个输入元素中的每一个都是在0到k区间内的一个整数,其中k为某个整数,当k=O(n)时,排序的运行时间为Θ(n)\Theta{(n)} 代码如下:void countingSort(vector<unsigned int>& array){ if(array.size()==0) throw underflow_error原创 2016-05-30 22:16:45 · 359 阅读 · 0 评论 -
第21章:用于不相交集合的数据结构
一:不相交集类的声明如下:#ifndef DISJSETS_H#define DISJSETS_H#include <vector>using namespace std;class DisjSets{public: explicit DisjSets(int); bool isSameSet(int x, int y) const { ret原创 2016-05-30 22:22:00 · 470 阅读 · 0 评论 -
第30章 多项式与快速傅里叶变换
这一章讲了多项式之间的乘法,但仅限于两个次数界相等并且为2的幂的多项式之间的乘法。运用了快速傅里叶变换及逆快速傅里叶变换算法。递归的快速傅里叶变换代码:void recursiveFFT(const vector<double>& coefficient,vector<Complex>& FFTResult){ int length=coefficient.size();原创 2016-04-24 20:52:10 · 647 阅读 · 0 评论 -
第4章 分治策略——strassen算法
strassen算法首先要求两个矩阵要是方块矩阵,并且维数是2的幂。如果两个矩阵不满足这两个条件,可以增加元素均为0的行与列以满足条件。假设要计算C=A*B。首先将A,B,C均分解为4个n/2*n/2的子矩阵。假设将A分解为A11,A12,A21,A22。 B分解为B11,B12, B21, B22。 对C做类似的操作。创建10个n/2*n/2的矩阵 S1,S2,…, S10。S1=B12-B2原创 2016-05-19 21:35:01 · 774 阅读 · 0 评论 -
第4章:分治策略 ——最大字数组问题
第四章 分治策略知识点总结这一章主要给我们介绍了分治算法,这算法由如下三个步骤组成分解步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小;解决步骤递归地求解这些子问题,如果子问题的规模足够小,则停止递归,直接求解;合并步骤将子问题的解组合成原问题的解。 递归式与递归算法时间复杂度的分析紧密相关,我们见到的递归式大部分情况下具有如下的形式:T(n)=aT(n/b)+f(n)原创 2016-05-19 21:29:14 · 373 阅读 · 0 评论 -
第31章:数论算法
最大公约数:欧几里得算法:对于任意非负整数a和任意正整数b来说,当求它们的最大公约数时,有如下定理:gcd(a,b)=gcd(b,a mod b);根据这个定理,可以写出求最大公约数的代码:// a和b是任意非负整数;//递归求解;unsigned long Euclid_Rec(unsigned long a,unsigned long b){ if(b==0)原创 2016-05-18 22:54:23 · 642 阅读 · 0 评论 -
第5章:概率分析与随机算法
知识点总结概率分析是在问题分析中应用概率的理念,必须要假设输入的分布,然后计算出一个平均情形下的运行时间,其中对所有可能的输入分布取平均值,得到的这种运行时间称为平均情况运行时间如果一个算法的行为不仅由输入决定,而且也由随机数生成器产生的数值决定,我们称这个算法是随机的。当分析一个随机算法的运行时间时,我们以运行时间的期望值来衡量,其中输入值由随机数生成器产生,我们称为期望运行时间。当我们在概原创 2016-05-19 21:39:30 · 1655 阅读 · 0 评论 -
第32章:字符串匹配问题: 朴素算法,Rabin-Karp算法
在文本编辑中,经常要找出某一个模式在一段文本中全部出现的位置。这可以用字符串匹配问题来求解,不过这一章节仅考虑长度有限的字符串。如果一个模式P(长度为m)是从文本T(长度为n)中第(s+1)个字符开始出现,我们则说模式p在文本T中出现并且位移为s(0<=s<=n-m)。本章节给出了求解字符串匹配问题的四种算法,分别是朴素算法,Rabin-Karp算法,有限自动机算法,Knuth-Morris-Pra原创 2016-05-22 20:21:53 · 428 阅读 · 0 评论 -
第22章:图的基本算法—广度优先搜索和深度优先搜索
1:在下面的代码中,用的是邻接表来表示图,声明如下:vector<list<int> > graph 2:有两种方法去遍历一个图,一个是广度优先搜索,另外一个是深度优先搜索广度优先搜索:代码如下:void graphType::breadthFirstTraversal(){ vector<bool> visited(gSize); for(int vertex=原创 2016-05-31 14:04:33 · 2663 阅读 · 0 评论 -
第22章:基本的图算法—拓扑排序和有向图强连通分量
三:拓扑排序:\quad对于一个有向无环图G=(V,E)来说,其拓扑排序是G中所有结点的一种线性次序,该次序满足如下条件:如果图G包含边(u,v),其结点u在拓扑排序中处于结点v的前面(如果图G包含环路,则不可能排出一个线性次序)。可以将图的拓扑排序看做是将图的所有结点在一条水平线上排开,图的所有有向边都从左指向右。代码如下:void dfs_visit(int source,vector<int>原创 2016-07-14 18:33:27 · 1231 阅读 · 0 评论 -
第23章:最小生成树
本章展示了两种最小生成树算法,一个是Kruskal算法,一个是prim算法。Kruskal算法:代码如下:void msTreeType::kruskalMinimumSpanning(){ int edgesAccepted=0; DisjSets dj(gSize); Edge e; int uVertex,vVertex;原创 2016-05-31 14:13:38 · 437 阅读 · 0 评论 -
第24章:单源最短路径
Dijkstra算法解决了有向图G=(V,E)带权的单源最短路径问题,但要求所有边的权值非负。下面给出Dijkstra算法代码:void weightedGraphType::shortestPath(int vertex){ source=vertex; for(int i=0;i!=gSize;i++) smallestWeight原创 2016-05-31 14:22:35 · 1103 阅读 · 0 评论 -
第25章:每对顶点间的最短路径—基于矩阵乘法的动态规划算法
下面给出一个基于动态规划的算法,void graph::shortestWeightsOfAllPairs(){ const int NOT_A_VERTEX=-1; shortestWeights.resize(gSize); shortestPath.resize(gSize); for(int i=0;i!=gSize;++i)原创 2016-05-31 14:33:32 · 4014 阅读 · 0 评论 -
第25章:所有结点对的最短路径问题—floyd-warshall和Johnson算法
二:Floyd-Warshall算法\quad该算法适用于边权重可以为负值,但环路权重和不能为负值的图,其运行时间为Θ(V3)\Theta(V^{3})。\quad假设dkijd_{ij}^{k}为从结点i到结点j的所有中间结点全部取自集合{1,2,…,k}的一条最短路径权重。当k=0时,从结点i到结点j的一条不包括编号大于0的中间结点的路径将没有任何中间结点。这样的路径最多只有一条边,因此d(0)原创 2016-07-15 19:14:55 · 2175 阅读 · 0 评论 -
第26章:最大流
下面给出代码求解一个图中的最大流:void networkFlow::pathWithMaxFlow(double& flow,vector<int>& path){ vector<bool> visited(gSize,false); vector<double> maxFlow(gSize,DBL_MIN); for(int i=0;i!=gSiz原创 2016-05-31 14:43:59 · 538 阅读 · 0 评论 -
第9章:中位数和顺序统计量
快速选择算法如下:template<class Type>void quickSelect(vector<Type>& array,int k,int left,int right){ //尾递归/* if(left<right){ if(10<=right-left){ int原创 2016-05-30 22:18:03 · 536 阅读 · 0 评论 -
第11章:散列表
下面代码用分离链接法实现散列表:1:将一个输入元素利用散列函数散列到某一个值:int hash(int key){ return key;}int hash(const string& key){ int hashVal=0; for(string::size_type ix=0;ix!=key.size();ix++)原创 2016-05-30 22:20:45 · 451 阅读 · 0 评论 -
第15章 动态规划
一: 分治算法和动态规划的区别:分治算法将问题分为互不相交的子问题,递归地求解子问题,然后再将它们的解组合起来,以求出原问题的解。动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题。如果用分治算法来求解重叠子问题的情况,分治算法会做许多不必要的工作,因为它会反复求解那些公共子子问题。而动态规划算法对每个子问题只求解一次,将解保存在一个表格中,如果随后再次需要此子问题的解,只需查找原创 2016-03-21 14:32:55 · 484 阅读 · 0 评论 -
第12章:二叉搜索树代码:
这章主要讲了二叉查找树及其相关性质。二叉搜索树的结点结构,插入,搜索,删除,结点后继,结点前驱,遍历代码如下。结点结构:struct node{ Type element;//存储的关键字 node* parent;//母结点 node* left;//左孩子结点 node原创 2016-03-06 00:06:33 · 360 阅读 · 0 评论 -
第16章 贪心算法
一:贪心算法的概念:求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临多重选择,动态规划算法是通过比较这么多选择来得到一个最优的选择,而贪心算法不用比较而是直接选出当时看起来最佳的选择,通过做出局部最优的选择来得到全局最优解。设计贪心算法有如下三个步骤:将最优化问题转化为这样的形式:对其做出一次选择后,只剩下一个子问题需要求解;证明贪心选择是最优解的一部分;证明做出贪心选择后,剩余原创 2016-04-02 20:36:34 · 480 阅读 · 0 评论 -
第13章 红黑树代码
红黑树本质是二叉搜索树,只是它有如下的额外条件每个结点要么为红色要么为黑色;根节点是黑色的 ;NULL结点是黑色的;如果一个结点是红色的,那么它的两个子节点都是黑色的;对每个结点,从该结点到其所有后代叶节点的简单路径上,均包含相同数目的黑色结点。之所以要有如下的额外条件,是为了保证树高为O(lgn)。因为在普通二叉搜索树中,树高为O(n),而不是O(lgn)。下面给出了结点左旋,结点右旋原创 2016-03-10 20:18:48 · 313 阅读 · 0 评论 -
第17章 摊还分析
在摊还分析中,我们通过求数据结构的一个操作序列中所执行的所有操作序列的平均时间来评价操作的代价,这个平均时间也称为摊还代价,它保证最坏情况下每个操作的平均性能。在分析摊还时间时,有三种分析方法可以采用,分别是聚合分析,核算法,势能法。聚合分析:利用聚合分析,我们证明对所有n,一个n个操作序列最坏情况下花费的总时间为T(n)。因此,在最坏情况下,每个操作的平均代价,或者是摊还代价为T(n)/n。需要注原创 2016-04-06 22:15:39 · 581 阅读 · 0 评论 -
第14章 数据结构扩张 区间树部分代码
下面给出了区间类定义,区间树类的结点结构,左旋,右旋,恢复插入引起的红黑树性质破坏,插入,恢复删除引起的红黑树性质破坏,删除,寻找重叠区间,寻找重叠区间但具有最小低端点,寻找重叠区间但具有最大低端点这一系列操作的代码。区间类定义:class interval{public: interval(const int& l=int(),const int& h=int()):lowEnd原创 2016-03-14 23:11:01 · 469 阅读 · 0 评论 -
第十四章 数据结构扩张 动态顺序统计部分代码
在这一章中,动态顺序统计和区间树被举例用来显示怎样去扩张一个数据结构。一般来说,扩张一个数据结构分为以下四个步骤:选择一种基础数据结构;确定基础数据结构中要维护的附加信息;检验基础数据结构上的基本修改操作能否维护附加信息;设计一些新操作。当然设计一个数据结构的扩张,没有那么顺利,永远包含着试探和纠错。下面给出基于红黑树的动态顺序统计和区间树的代码。动态顺序统计:下面代码给出了左旋,右旋,恢原创 2016-03-14 22:40:38 · 333 阅读 · 0 评论 -
第13章部分习题答案
思考题13-1。其五个小问a,b,c,d,e答案如下:a:当插入一个关键词时,从根到新插入结点x路径上的所有结点都需要被改变,因为这个新插入结点x的地址值需要赋值给一个结点的孩子指针,那么这个结点需要被新建,同样,也需要孩子结点指向这个新节点,以此类推,一直到根。当删除一个结点时,如果这个要被删除的结点z最多只有一个孩子,那么这个要被删除结点z的所有祖先均需要被改变。否则的话找到这个要被删除结点原创 2016-03-12 01:07:06 · 587 阅读 · 0 评论 -
第28章 矩阵运算
这一章给出了求解线性方程组Ax=b(|A|!=0)和求矩阵的逆的伪代码,下面用c++实现。线性方程组:1: 先求出P,L,U,使得PA=LU成立void LUPDecomposition(vector< vector<double> >& array,vector<int>& P){ int dimension=array.size(); P.resize(dimen原创 2016-04-16 12:44:48 · 498 阅读 · 0 评论 -
第32章 :字符串匹配—有限自动机算法,Knuth-Morris-Pratt算法
有限自动机算法:一个有限自动机M是一个5元组(Q,q0,A,Σ,δ)(Q, q_{0}, A, \Sigma, \delta),其中:1:Q 是状态的有限集合; 2:q0q_{0}(属于Q)是初始状态; 3:A(属于Q)是特殊的接收状态的集合; 4:Σ\Sigma是有限输入字母表; 5:δ\delta是一个从Q×ΣQ\times\Sigma到Q的函数,称为M的转移函数;有限自动机开始于状态q原创 2016-05-26 23:28:57 · 1888 阅读 · 0 评论 -
第29章:线性规划
这一章讲解了如何用单纯行算法解决线性规划问题。下面给出用c++实现的代码,输入为标准型线性规划。先给出单纯行算法的驱动部分,代码如下://求解一个输入为标准型线性规划的问题。double simplex(vector< vector<double> >& A,vector<double>& b,vector<double>& c,vector<double>& solution){原创 2016-04-19 21:27:09 · 685 阅读 · 0 评论 -
第六章:堆排序
一:二叉堆的基本操作:假设我们要实现的是一个最小堆:1:插入操作代码:template<class Type>void binaryHeap<Type>::insert(const Type& val){ if(currentSize==array.size()-1) array.resize(array.size()*2); in原创 2016-05-30 20:14:20 · 318 阅读 · 0 评论 -
第33章 :计算几何学
一:判定给定的两条线段是否相交:当两条线段的四个点p1,p2,p3,p4给定时,如下的代码能够判断线段p1p2与线段p3p4是否相交,如果相交则返回true,否则返回false;//pair<double,double>第一个元素存储坐标点的x坐标,第二个元素存储坐标点的y坐标using point=pair<double,double>;// 计算矢量(pk-pi)与矢量(pj-pi)的叉乘原创 2016-05-30 19:56:50 · 414 阅读 · 0 评论 -
第2章:算法基础
1:插入排序:代码如下:template<class Type>void insertionSort(vector<Type>& a){ for(typename vector<Type>::size_type i=1;i!=a.size();i++) { Type tmp=a[i]; typenam原创 2016-05-30 20:21:09 · 314 阅读 · 0 评论 -
第7章:快速排序
随机化快速排序:1:对数组的随机划分:int random(int i,int j){ return rand()%(j-i+1)+i;}template<class Type>int partition(vector<Type>& array, int left,int right){ Type compareVal=array[right];原创 2016-05-30 20:30:00 · 307 阅读 · 0 评论 -
第31章 数论算法:元素的幂以及模取幂
元素的幂:在这里介绍求元素的幂X^n(X和n均为非负整数)的两种算法,一个是递归求解,另外一个是用反复平方法递归求解:当我们计算X^n时,当n=0,结果为1,这可以看做递归的基准情况,当n为偶数时,X^n=(X^2)^(N/2),当n是基数时,X^n=(X^2)^((n-1)/2)*X。代码如下:bool isEven(unsigned int n){ if(n%2==0) ret原创 2016-05-22 13:14:31 · 1217 阅读 · 0 评论