算法导论
文章平均质量分 72
liuzhanchen1987
这个作者很懒,什么都没留下…
展开
-
算法导论第十五章习题15.4-5
在O(n^2)内求n个数的最长单调递增子数列。思路:利用动态规划的思路求解。c[i]存放到第i个数时,最长递增子数列的长度。b[i]存放比第i个数小的第j个数的下标(j代码如下://最长递增子数列O(n^2)时间复杂度内完成。//采用动态规划方法#include using namespace std; int LongestUpSeries(int *n,int leng原创 2012-08-10 18:29:19 · 5324 阅读 · 4 评论 -
算法导论第十六章--贪心算法
贪心算法:代码为算法导论课本例题。//贪心算法#includeusing namespace std;int GreedySelect(int *s,int *f,int length,int *a){ int i,j=2; a[1]=1; i=1; for(int m=2;m<=length;m++) { if(s[m]>=f[i]) { a[j++]=m;原创 2012-08-11 15:32:45 · 3597 阅读 · 0 评论 -
算法导论第十五章习题15-1--双调欧几里得旅行商问题
思路:1),首先将所有点加上坐标,x轴指向右,y轴指向下。然后将所有点按照x轴坐标从小到大排列。2)总体思路是依次从排好序的节点取出一个节点,决定该节点应该放在第一条路径上还是第二条路径上。 3)定义一个数组:double b[8][8]; //b[i][j]表示第一条路径搜索到第i各节点,第二条路径搜索到第j个节点后的最短路径长度。如果i==j则说明两条路径汇聚到i点上如果i==n则说原创 2012-08-11 10:50:43 · 4973 阅读 · 0 评论 -
算法导论第十章习题10.4-2
递归形式实现二叉树的遍历:中序遍历,前序遍历,后序遍历;代码如下:本代码为整个二叉树中部分函数截取,其余代码请参考算法导论第十章-二叉树的实现。void InOrder(BintreeNode* node) { BintreeNode*p=node; if(p!=NULL) { InOrder(p->left); coutkey<<" "; InOrder(原创 2012-07-25 20:22:45 · 1894 阅读 · 0 评论 -
算法导论第十五章习题15.4-4c++代码实现
只用两行表c就能实现计算LCS长度的算法。因为在计算长度的时候c[i][j]只需要上一行以及本行的计数就能计算出结果,所以我们只用两行表c来实现。每当第二行的长度计算完成之后,便将第二行的长度赋给第一行,而第二行清0,这样计算下一行的时候,第一行就能使用上一层循环中的长度。代码如下:#include#includeusing namespace std;int LCS_Length(st原创 2012-08-10 15:50:48 · 1458 阅读 · 0 评论 -
算法导论第十五章习题15.4-2
不适用数组b就能实现LCS结果的打印,代码如下://LCS#include#includeusing namespace std;//改进的LCS算法,不使用数组b便可打印出结果void LCS_LengthC(string x,string y,int (*c)[100]){ int m,n; m=x.length(); n=x.length(); int i,j;原创 2012-08-10 14:37:45 · 3162 阅读 · 0 评论 -
算法导论第15章习题15.3-3最大矩阵链乘法
15.3-3思路供参考:确定一个问题是否具有最优子结构要考虑两个方面的问题:1、子问题是否是独立。2、子问题是否是重叠先分析第一个问题:最大矩阵链乘法子问题是将矩阵链分为两部分,求前一部和后一部分最大值,然后合并,而这两个子问题的 最大值是在两个矩阵链中分别求解,所以这两个子问题没有重复(在这里最鲜明的对照就是无权图中最长简单路径问题,该问题如果分为两个子问题,前一部分的最长路径可能包含后一部原创 2012-08-10 10:54:57 · 4238 阅读 · 0 评论 -
算法导论第十章习题10.4-3非递归方式实现二叉树的中序遍历
非递归方式实现二叉树的中序遍历:迭代方式: //非递归中序遍历 void NonReInOrder(BintreeNode* node) { BintreeNode*p=node; stacks; s.push(p); bool flag=0; while(!s.empty()) { p=s.top(); //flag标志位。如果flag为0则沿着树向下原创 2012-07-25 20:24:47 · 2175 阅读 · 0 评论 -
算法导论第十一章习题11.1-4
题目:我们希望我们希望通过利用在一个非常大的数组上直接寻址的方式来实现字典。开始时,该数组中可能包含废料,但要对整个数组进行初始化是不实际的,因为该数组的规模太大。请给出在大数组上实现直接寻址字典方案。每个存储的对象占用O(1)的空间;操作search,insert,delete的时间为O(1);对数据结构初始化时间为O(1)。 (提示:可以利用另外一个栈,其大小等于实际存储在字典中的关键字数原创 2012-07-26 10:43:16 · 2018 阅读 · 1 评论 -
算法导论第十五章---最长公共子串LCS代码实现
详细分析见算法导论。代码如下://LCS#include#includeusing namespace std;void LCS_Length(string x,string y,int (*c)[100],int (*b)[100]){ int m,n; m=x.length(); n=x.length(); int i,j; //如果i或j等于0则c[i][j]=0;原创 2012-08-10 14:16:21 · 2496 阅读 · 0 评论 -
算法导论第十五章--动态规划的变形(做备忘录的递归算法)
动态规划中的 循环结构可以通过递归的方式实现,但是单纯的递归方法每次都会将已计算过的子问题重新计算,时间复杂度较高,因此可以通过在递归中做备忘录的方法建设时间复杂度。具体见代码:#includeusing namespace std;//动态规划的一种变种,通过在递归的算法中添加备忘,来维护记录子问题的表格。这种方法是一种自顶向下的//方法,该方法优于单纯的递归调用,因为单纯的递归原创 2012-08-10 10:17:46 · 3405 阅读 · 1 评论 -
算法导论第十章-二叉树的实现
BintreeNode.h二叉树节点头文件#includeusing namespace std;class Bintree;class BintreeNode{private: friend Bintree; int key; BintreeNode* left,*right;public: BintreeNode() { right=NULL; left=NU原创 2012-07-25 20:19:35 · 1485 阅读 · 0 评论 -
算法导论第十章--队列的实现
queue.h#includeusing namespace std;#define Max 20class queue{private: int length; int *head; int *tail; int Node[Max];public: queue():length(0) {// head=new int;// tail=new int; }原创 2012-07-25 09:32:12 · 852 阅读 · 0 评论 -
算法导论16.2-2 0-1背包问题
0-1背包问题使用动态规划算法。空间未优化的代码:#includeusing namespace std;int Max(int i,int j){ return i>j?i:j;}void KnapSack(int *w,int *p,int (*f)[30],int length,int volume){ int i,j; for(i=w[1];i<=volume;i原创 2012-08-11 17:46:07 · 2714 阅读 · 0 评论 -
算法导论第十一章散列表的实现(哈希表的实现)
该散列表的散列函数采用了除法散列函数、乘法散列函数、全域散列函数,每一个槽都是使用有序单向链表实现。LinkNode.h#includeusing namespace std;class Link;class LinkNode{private: int key; LinkNode* next; friend Link;public: LinkNode():key(-1)原创 2012-07-26 16:44:23 · 2156 阅读 · 1 评论 -
算法导论第十五章--最优二叉查找树
利用最优二叉查找树来实现树的搜索代价最小。树上的每一个节点都有一个被搜索到的概率值,搜索一个节点的花费为概率*(深度+1),如何构造一个二叉查找树使搜索树上的 所有节点的花费最小即为实现最优二叉查找树的问题。该问题可以用动态规划的思路实现。具体解释见算法导论。代码如下://最优二叉查找树,利用动态规划实现。霍夫曼树。#includeusing namespace std;void Opt原创 2012-08-10 21:38:25 · 4618 阅读 · 0 评论 -
算法导论第十三章习题13-3——AVL树(高度平衡树)C++代码详细实现
AVL树是一种高度平衡树,对于每一个节点,其左子树的高度与右子树的高度相差之多为1。AVL树是比红黑树更加平衡的树(红黑树中左右子树高度之比小于2)。AVL树除了平衡性较好外,与普通的二叉查找树没什么大的区别。所以AVL树的代码实现可以基于前面的二叉树实现代码算法导论第十二章——二叉查找树的C++代码实现来实现。实现AVL树的关键在于维持树的平衡性。所以每插入一个节点或删除都有可能要对树进原创 2012-08-03 16:06:58 · 5418 阅读 · 11 评论 -
算法导论第32章——字符串匹配问题(KMP算法)
下面代码列举了普通字符串匹配算法和KMP算法。KMP算法原理见算法导论第32章。代码中有简单的注释可以帮助理解:#include#includeusing namespace std;#define MAX 10000//KMP算法时间复杂度为O(n+m),其中n为str的长度,m为pat的长度void kmp(string str,string pat){ boo原创 2012-09-01 11:10:41 · 3053 阅读 · 0 评论 -
算法导论第十九章二项堆
自己写的bug应该很多BinHeapNode.h#includeusing namespace std;class BinHeap;class BinHeapNode{private: friend BinHeap; int key; BinHeapNode*parent; BinHeapNode*child; BinHeapNode*sibling; int deg原创 2012-08-15 15:24:23 · 1511 阅读 · 0 评论 -
算法导论第十三章--红黑树C++代码实现
红黑树的性质,各个操作的具体步骤在透彻了解红黑树之一 透彻了解红黑树之二 透彻了解红黑树之三 透彻理解红黑树之四 透彻理解红黑树之五,中已经讲的很详细了,在这里只将代码实现贴出来:BRTreeNode.h#includeusing namespace std;class BRTree;class BRTreeNode{private: frien原创 2012-07-31 22:31:41 · 5475 阅读 · 5 评论 -
算法导论第十二章习题12.3-1---二叉树插入的递归版本
二叉树插入元素num的递归版本,在上一篇算法导论第十二章——二叉查找树的C++代码实现中,实现了二叉树插入元素的非递归版本,本代码可以直接放入到上一篇的BinTree.h的头文件中。代码如下://递归版本 void ReInsert(BinTreeNode* node,BinTreeNode* start) { BinTreeNode* p=start; if(p->k原创 2012-07-30 09:56:50 · 2544 阅读 · 0 评论 -
算法导论第十二章——二叉查找树的C++代码实现
二叉排序树(Binary Sort Tree)又称二叉查找树。 它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树;二叉排序树的查找 步骤:若根结点的关键字值等于查找的关键字,成功。 否则,若小于根结原创 2012-03-06 15:14:28 · 4003 阅读 · 4 评论 -
算法导论第十八章B树
B树:BTreeNode.h#includeusing namespace std;class BTree;class BTreenode{private: friend BTree; //存放键值的数组 int * pkey; //当前有多少键值 int currentsize; //最大存放的键值 int maxsize; BTreenode* parent;原创 2012-08-14 15:18:32 · 2292 阅读 · 0 评论 -
算法导论第十一章习题11.2-4
该算法是在上一篇文章的基础上进行改进而得到的,跟上一篇比较,本代码添加了head头文件,Head即为散列表中的每一个槽,该槽包含执行上一个空槽的pre节点,指向下一个空槽的next节点,指向链表Link的table节点和指示该槽是否为空的标志位flag,flag为1时表示槽位有元素,否则为空。Hash头文件较上一篇文章,较大的改进是Insert函数和Delete函数,主要是添加了如何将刚刚空出原创 2012-07-29 11:09:05 · 2312 阅读 · 0 评论 -
算法导论第十一章11.4例题——开放寻址法代码实现
本代码根据开放寻址法的三种方法——线性探查、二次探查、双重探查法实现散列表的插入,删除,寻找。开放寻址法一个槽只插入一个元素,完全避免冲突,但是查找时间可能会增大。以上三种方法要做到降低集群现象的发生(即大量的元素密集的排列在散列表中的某一段区域,这样会增加插入查找的时间复杂度)。具体代码如下://开放寻址法//散列函数包括线性探测、二次探测、双重探测#includeusin原创 2012-07-29 16:24:34 · 3741 阅读 · 2 评论 -
算法导论第十五章--霍夫曼编码
这道题纠结了一天,本想用简单点的方法实现,可是反而弄巧成拙。不过通过写该代码学会了如何使用优先级队列,对优先级队列有了进一步的了解。代码如下:其中难度较大的是优先级队列的使用,详细的使用方法请参考博主的另一篇文章优先级队列的基本应用//在优先级队列中存入指针类型的节点#include#include#includeusing namespace std;class Comapre原创 2012-08-12 18:54:51 · 1681 阅读 · 0 评论 -
算法导论16.2-6
在O(n)时间范围内解决部分背包问题。思路:利用快排的思想将数组分为三部分,A,B,C,其中B只包含划分区域的主元一个元素。计算A中物品的重量,如果超过了volume,则继续对A进行划分。如果w(A)W(A+B),则A,B都入包,同时对C进行划分代码如下://在O(n)时间内解决部分背包问题。//思路是:不用将性价比的数组所有元素都进行排列,利用快排思想//将数组分成三组#i原创 2012-08-11 22:43:12 · 2931 阅读 · 0 评论 -
算法导论第十六章习题16.1-2
从最后一个开始的活动开始选择,则各个活动开始时间要进行排序。代码如下://贪心算法#includeusing namespace std;//选择最先结束的活动int GreedySelect(int *s,int *f,int length,int *a){ int i,j=2; a[1]=1; i=1; for(int m=2;m<=length;m++) { if原创 2012-08-11 15:53:48 · 6359 阅读 · 0 评论 -
算法导论第十章例题-栈的实现
StackNode.h#includeusing namespace std;class Stack;class StackNode{private: friend Stack; int key; StackNode *Next;public: StackNode(int num):key(num),Next(NULL){} int Getkey() { retur原创 2012-07-25 09:30:43 · 937 阅读 · 0 评论 -
算法导论第九章习题9.3-7
在O(n)时间范围内找出数组a[n]中位数相邻的k个数字思路:简单的思路是先找出中位数(n+1)/2然后依次找第(n+1)/2-1小数字、(n+1)/2-2小数字、(n+1)/2-3.小数字。。。。(n+1)/2-k/2小数字,再找第(n+1)/2+1小数字、(n+1)/2+2小数字、(n+1)/2+3.小数字。。。。(n+1)/2+(k+1)/2小数字。但是该算法时间复杂度为O(kn)。原创 2012-07-24 10:24:48 · 2470 阅读 · 5 评论 -
算法导论9.3-6
题目:对一个含有n个元素的集合来说,所谓k分位数(the kth quantile),就是能把已排序的集合分成k个大小相等的集合的k-1个顺序统计量。给出一个能列出某一集合的k分位数的O(nlgk)时间的算法思路:每个子集合的元素个数为t = n / k,A[j]是数组A中下标为j的元素,A(j)是数组是第j大的元素则所求的k分位数是指A(t),A(2t),A(3t),……,A((原创 2012-07-23 15:39:10 · 2520 阅读 · 0 评论 -
算法导论习题7-6
题目:考虑这样一种排序问题,即无法准确的知道等排序的各个数字到底是多大.对于其中的每个数字,我们只知道它落在实轴上的某个区间内.亦即,给定的 n 个形如[ai, bi ]的闭区间,其中ai,≤bi .算法的目标是对这些区间进行模糊排序(fuzzy-sort),亦即,产生各区间的一个排序1, i2, i3, i4,…in >,使得存在一个 cj ∈[ai, bi ],满足c1≤c2≤原创 2012-07-03 12:12:08 · 1060 阅读 · 0 评论 -
算法导论习题7-3 Stooge-Sort
stooge-sort的主要思想是分治,将数组划分为三个区间,对前两个区间中的第一个元素和最后一个元素比较,如果第一个大于最后一个互换位置,然后对后两个区间中的第一个和最后一个元素比较,如果第一个大于最后一个互换位置,然后再对前两个区间中的第一个元素和最后一个元素比较,如果第一个大于最后一个互换位置,以上所述的步骤是递归执行的,最底层的递归是三个元素的比较:比如为3,1,2.先比较3,1, ,并互原创 2012-07-02 15:10:45 · 3099 阅读 · 0 评论 -
算法导论习题7-4—快排中堆栈深度的优化
//Quick_sort//time complexity is nlgn//the way is find an element,and partition the array according to this element#includeusing namespace std;int Partition(int a[],int p,int r){ int num=a[r];原创 2012-07-02 20:01:02 · 2789 阅读 · 2 评论 -
算法导论6.5-8
题目:k个已排序链表,元素总数是n,要求在nlgk时间复杂度内把k个链表合并为一个有序链表。思路:取k个链表中每一个链表的第一个元素,共k个,将这k个元素建立一个最大堆(或最小堆),取出堆中的第一个元素放到数组str中,将堆中第一个元素所对应的链表中的该元素去掉,链表中的第二个元素上升为第一个元素。并把该元素插入到最大堆中的根节点,调整最大堆,然后仍然取出堆中根元素放入到str中,将该元素对应原创 2012-07-01 15:52:30 · 1172 阅读 · 1 评论 -
算法导论第六章之——优先队列
优先队列类模版实现:BuildMaxHeap.h头文件:#includeusing namespace std;#define Left(i) i*2+1#define Right(i) i*2+2#define Parent(i) (i-1)/2void Max_Heapify(int a[],int length,int i){ int left,right; left原创 2012-06-30 19:53:28 · 833 阅读 · 1 评论 -
算法导论习题6.2代码实现
利用D叉堆排序实现:#includeusing namespace std;#define Fork 5#define Parent(i) ((i-1)/Fork)#define Sib1(i) (Fork*i+1)#define Sib2(i) (Fork*i+2)#define Sib3(i) (Fork*i+3)#define Sib4(i) (Fork*i+4)#de原创 2012-07-01 20:47:14 · 944 阅读 · 0 评论 -
算法导论例题及课后习题代码实现——第六章
例题1,堆排序,在该堆排序中Max_Heapify函数分别用递归和循环实现 #includeusing namespace std;#define Left(i) i*2+1#define Right(i) i*2+2#define Parent(i) (i-1)/2void Max_Heapify(int a[],int length,int i){ int left,ri原创 2012-06-29 22:33:10 · 1175 阅读 · 0 评论 -
算法导论第二章课后习题代码实现
插入排序代码实现:#includeusing namespace std;void Insert_sort(int a[],int length){ int i,j,key; for(i=1;i<length;i++) { key=a[i]; j=i-1; while(key<a[j]) { int temp; temp=a[j+1]; a[j+1原创 2012-06-29 11:27:13 · 1263 阅读 · 2 评论 -
算法导论习题8.3-4
对0到n^2-1范围内的数字进行排序,要求时间复杂度为O(n)。可以直接采用基数排序法对其排序,但是这些数字为已知范围,所以有更进一步的优化,即将所有的数字转换成n进制,这样这些数在n进制下只有两位,即只需要比较2O(n)即可。转换成n进制消耗2O(n),所以对于比较的数字为四位以上时,该算法较普通的基数排序有优势。具体代码如下:修改:此处的插入排序应该改为计数排序。因为插入排序时间复原创 2012-07-04 09:30:08 · 3511 阅读 · 0 评论