- 博客(74)
- 资源 (10)
- 收藏
- 关注
原创 对kosaraju算法的理解思路
这个算法网上很多介绍,但大多都很相似,着重介绍算法实现而没有证明或者容易理解的解释。我说下自己对kosaraju算法的理解思路。这个算法名字我不会读,搜了半天看到本尊,发现他长得像印度人,也就释然了。回正题。kosaraju算法用来求一个有向图的所有强连通分量,算法很简单,但是理解起来有点麻烦,我是这么觉得。但是跟无向图的连通分量求法结合起来,就非常容易理解了。所以理解这个Korasaju算法的前
2012-11-28 12:12:04 10139 1
原创 可靠数据传输RDT(Reliable Data Transfer)
可靠资料传输(Reliable Data Transfer 简称rdt)资料可靠度是网络传输中非常大的问题之一。在TCP抽象服务的模型中(也算是理想状态),每个应用程序的讯息都透过网络上可靠的通道来传输,然而现实中的困难是 可靠传输协定的下层是不可靠。也就是说,现实中存在着许多状况,例如资料位元错误、封包遗失等等 造成资料的不可靠,必须建立有效的传输协定。1、rdt1.0rdt的
2012-06-13 14:51:08 15380
原创 第十五章动态规划之“最优二叉查找树”
本书从文字翻译的案例切入,假设把英文翻译为法文,每个英文单词为关键字,其对应法文为卫星数据。用二叉查找树存储,该怎么设计这个查找树。即使是红黑树,查找的时间复杂度也为O(lgn)即树的深度。但是因为文章中某个单词出现的频率不同,所以可能有些频率很高的单词比如the的深度可能很深,而不常见的Aha的深度却可能很浅。根据直觉,我们应该让本例中the更加靠近树根才对(其实即使概率最高也不见得就是树根)。
2012-05-05 15:12:05 1699
原创 第十五章动态规划之“O(n^2)时间寻找n个数构成序列的最长递增子序列”(练习15.4-5)
这个问题类似于两个序列的最长公共子序列问题,但是这里只有一个序列啊?肿么办?想想这个n个数的序列,要想找它最长递增子序列,这个子序列肯定是从小到大排序的,从小到大排序的耶!跟谁对应呢?思路来了!先把原序列从小到大排序,然后跟原序列对比寻找最长公共子序列!排序时间为O(nlgn),两个长度为n的序列寻找最长子序列为O(n^2),所以总的时间复杂度为O(n^2)。代码:#inclu
2012-05-04 22:16:13 2453
原创 第十五章动态规划之“最长公共子序列”
时间复杂度为O(m*n),就是两个循环。#include using namespace std;void LCSLength(char *x,char *y,int m,int n,int (*c)[7],int (*b)[7]){ for(int i=0;i<=m;i++) { c[i][0]=0; } for(int i=0;i<=n;i++) { c[
2012-05-04 21:44:36 1078
原创 第十五章动态规划之“矩阵链乘法”
装配线调度与矩阵链乘法是很典型的动态规划的两个例子。关于这俩例子对于理解动态规划的作用稍后补上。这个程序的时间复杂度为Ω(n^3),这个可以通过替换法证明。输出最优加括号的代码对于理解递归很有帮助,蹭蹭蹭,先往回跑,路上什么也不干,跑到头再跑回来,把该干的都干了,先自顶向下,再自底向上。代码如下:#include using namespace std;void MatrixCh
2012-05-04 08:55:45 1942
原创 第十五章动态规划之“装配线调度”
动态规划研究的问题与分治法区别:动态规划的子问题不是相互独立的,而是有交集,即子问题相互重叠,为了避免重复计算重叠的子问题,所以选择从底向上的迭代,以后用到直接查表。从而将装配线调度的复杂度从O(2^n)降到了O(n)。代码如下:#include using namespace std;void FastestWay(int (*a)[7],int (*t)[7],int *e,i
2012-05-03 13:41:42 897
原创 数据挖掘之FP-Tree算法
算法细节见论文:Mining Frequent Patterns Without Candidata Generation这篇论文是Jiawei Han的大作,又一个牛逼的中国人去了北美。图形化界面的工程+测试用例戳这http://download.csdn.net/detail/michealtx/4266155控制台版C++代码如下:#include #i
2012-04-29 20:32:23 4557
原创 数据挖掘之关联规则挖掘之Apriori算法实现
算法细节见论文:Fast Algorithm for Mining Association Rules 图形化版本工程+测试用例下载戳这http://download.csdn.net/detail/michealtx/4266155控制台版本C++代码如下:#include #include #include #include #include #include
2012-04-29 20:19:31 4836 3
原创 数据挖掘之关联规则挖掘之SETM算法实现
具体算法实现细节请查看IEEE论文:Set-oriented mining for association rules in relational databasesSETM算法代码+测试用例+具体操作步骤下载戳这http://download.csdn.net/detail/michealtx/4266085sql语言实现,找出来所有的频繁模式。代码如下:--------
2012-04-29 19:50:56 3261
原创 第十二章Trie树(字典树)解决HDU1251
http://acm.hdu.edu.cn/showproblem.php?pid=1251 #include using namespace std;struct TrieNode{ TrieNode *children[26]; bool flag; int cnt;//前缀数目};void InitTrieNode(TrieNode *t
2012-04-19 17:05:08 1288
原创 第十二章二叉查找树
二叉查找树的查找(查找某个值、查找最小元素、查找最大元素)、插入、删除操作的最坏时间都为O(h)。构造二叉查找树时采取随机算法,可以让二叉查找树的期望高度为O(lgn),则前面那些操作的最坏时间就可以为O(lgn)。非常高效的算法。代码如下:#include using namespace std;struct TreeNode{ int key; TreeNode *p;
2012-04-19 10:56:05 1211
原创 第九章中位数和顺序统计学 之 “寻找第i小元素之最坏情况线性时间的选择 最坏运行时间就为O(n)算法”
使用这个算法查找第i小元素的最坏情况运行时间为O(n)。关于运行时间的证明简直屌爆了!唉,看了这么多证明,我发现其实最难的就是提出数学模型、数学描述,迈出这一步,剩下的就是凑了。这个算法比9.2节中那个“期望运行时间才是O(n)”的RandomizedPartition算法更加牛逼,它最坏运行时间就是O(n)。之所以这么屌,是因为它每次划分都能保证是最佳划分,即“中分”。要想实现中分,
2012-04-16 22:01:52 3733
原创 第五章概率分析和随机算法之练习5.3-6
题目:解释如何实现算法PERMUTE-BY-SORTING,来处理两个或更多优先级相同的情况。即,即使有两个或更多个优先级相同,你的算法也必须产生一个均匀随机排列。刚才在百度算法吧看到有人提出这个问题,居然将近四年没人回答。我回复了一下那个帖子,顺便把自己的看法复制到这里。若有问题,请路过的大牛帮助斧正,不胜感激。我的解答:打比方有a,b,c,d这个序列,我们用
2012-04-14 14:29:33 2035 2
原创 第九章中位数和顺序统计学之“查找第i小的元素(迭代版)平均运行时间为O(n)算法”(练习9.2-3)
这个是相对前一篇文章来说的,这是个迭代版本。递归化为迭代的一个关键点,就是看递归调用时,哪些参数值发生改变,然后针对这个参数设计循环。#include #include #define BUFFER_SIZE 10int RandomizedPartition(int *a,int p,int r){ int i=0; int j=0; int tmp=0; int x
2012-01-17 19:03:08 1341
原创 第九章中位数和顺序统计学之“查找第i小的元素(递归版)平均运行时间为O(n)算法”
类似于快速排序的随机化版本,但是这里每次只处理划分的一侧。最坏情况下时间复杂度为O(n^2),即每次都是按最大区间进行划分。但在平均情况下,任何顺序统计量(特别是中位数)都可以在线性时间内得到,时间复杂度为O(n)。#include #include #define BUFFER_SIZE 10int RandomizedPartition(int *a,int p,in
2012-01-17 15:41:48 1155
原创 第九章中位数和顺序统计学之“寻找第2小元素”(练习9.1-1待改进)
在最坏的情况下,利用n+(lgn的上限)-2次比较,即可找到n个元素中的第2小元素。(提示:同时找最小元素)#include #include #define BUFFER_SIZE 10void FirstAndSecond(int *a,int len,int *first,int *second){ int i=0; int j=0; if(a[0]<a[1
2012-01-17 15:09:34 960
原创 第九章中位数与顺序统计学之“同时找出最小值和最大值”
在一个数组同时找出最小值和最大值。可以分别找出最小值,比较n-1次;找出最大值,比较n-1次,共比较2n-2次。其实还有更少的比较次数。就是成对的处理元素,先将一对输入元素互相比较,找出最小值和最大值,然后再用最小值与当前的最小值比较得出新的最小值,用最大值和当前最大值比较,得出新的最大值,所以这一对元素共比较了3次。n个元素则只需比较3*((n/2)的下限)次。当然对于n为偶数和奇数,处理过
2012-01-10 20:59:26 1841
原创 第八章线性时间排序之“桶排序BUCKET-SORT”
要对n个数进行排序,就要准备n个桶。先对n个数归一化,就是把它们除以一个较大的数,使之分布在【0,1)之间,然后对每个桶中的数插入排序,最后合并n个桶。时间复杂度为O(n)。#include #include typedef struct _Node { double value; struct _Node *next;}Node;#define BUFFER_SI
2012-01-10 16:39:00 797
原创 坏蛋unsigned int型造成的循环陷阱
下面的循环执行几次呢?unsigned int i=10;for(i=10;i>=0;i--){ printf("HELLO GIRL!\n");}11次?O(∩_∩)O~,其实它是个死循环!为虾米?因为i是个unsigned int型,当减小到0时,再减1变成2^32-1,判断条件仍然成立!把判断条件写成i!=0就好了。我好像在C++ Primer上
2012-01-10 11:18:52 1072
原创 第八章线性时间排序之“基数排序RADIX-SORT”(练习8.3-1)
利用基数排序对a[17][4]={" ","COW","DOG","SEA","RUG","ROW","MOB","BOX","TAB","BAR","EAR","TAR","DIG","BIG","TEA","NOW","FOX"}进行排序。“基数排序”可以看做给“计数排序”创造条件,一般的小数用基数排序很麻烦,而且效率不如计数排序,但是要是n个长度为b的长整数或者字符串,可以先用r(r
2012-01-10 09:45:18 955
原创 第八章线形时间排序之“计数法排序COUNTING-SORT”
这个方法很牛逼,这个排序方法不再像前面那些排序方法一样根据比较来进行。时间复杂度为O(k+n+k+n+n)=O(n),当k=O(n)时,可以保证时间复杂度为O(n),就可以用计数法来进行排序了。这个方法的一个前提是必须要知道要排序的数组中元素的取值范围。#include #include #define BUFFER_SIZE 10void CountingSort(in
2012-01-09 14:53:30 914
原创 第七章快速排序之“区间模糊排序FUZZY-SORT”(待改进。。。)
快速排序可以看成区间大小为1的模糊排序。#include #include #define BUFFER_SIZE 10typedef struct{ int start; int end;}Node; int FuzzyPartition(Node *a,int p,int r){ Node tmp; int i=0; int j=0; int k=0; N
2012-01-07 17:14:03 1194
原创 第七章快速排序之“采取“尾递归”和“三数取中”技术的快速排序”(思考题7-4、7-5)
QUICKSORT算法包含两个对其自身的递归调用,即调用PARTITION后,左边的子数组和右边的子数组分别被递归排序。QUICKSORT中的第二次递归调用并不是必须的,可以用迭代控制结构来代替它,这种技术叫做“尾递归”,大多数的编译器也使用了这项技术。最坏的情况下,就是划分不好的时候,递归深度为O(n),能够二分的话递归深度为O(lgn),但是怎么才能得到好的划分呢?前面在快速排序中用了个随机化
2012-01-06 17:04:52 3780
原创 第七章快速排序之“快速排序Hoare版本HOARE-QUICKSORT”(思考题7-1)
这是个历史更早的版本,Hoare是人名,这个版本的Partition()函数跟现在的不一样。我觉得这个老版本不如现在的版本好理解,大面上看起来可能好理解,但是具体写代码时考虑指针移动,很麻烦。#include #include #define BUFFER_SIZE 10int HoarePartition(int *a,int p,int r){ int tmp=0
2012-01-05 22:05:05 2384
原创 第七章快速排序之“快速插入排序”(练习7.4-5)
O(∩_∩)O~,这个名字乍听起来比较黄。其实就是先快速排序进行划分,等划分小到一定规模比如k时,进行插入排序,因为规模小到一定程度,插入排序的效率更高。我在前面还写过一个合并插入排序的算法,思想跟这个相似。总的时间复杂度为O(nk+nlg(n/k)),这个很好证明:先进行二分,划分到规模都为K时停止划分,此时深度为h,则T(n/2^h)=k,则h=lg(n/k),最底层规模为K的叶节点数
2012-01-05 22:03:27 3367
原创 第七章快速排序之“快速排序的随机化版本RANDOM-QUICKSORT”
因为快速排序的最坏情况是O(n^2),最佳情况是O(nlgn),采用随机化版本时间复杂度可以达到平均情况O(nlgn)。书上的证明过程让人心静、让人谦卑,its amazing!比起那些让人拍案叫绝的证明过程,用代码实现反而不是最重要的了。#include #include #define BUFFER_SIZE 10int Partition(int *a,int p,
2012-01-05 17:13:48 1666
原创 第七章快速排序之“快速排序QUICKSORT”
#include #include #define BUFFER_SIZE 10int Partition(int *a,int p,int r){ int x=0; int i=0; int j=0; int tmp=0; x=a[r]; i=p-1; for(j=p;j<r;j++) {//将数组划分为四个区,(a[p]~a[i])x,(a[j]~a[r-1])
2012-01-05 09:47:42 737
原创 第六章堆排序之“Young氏矩阵(Young tableau)”(思考题6-3)
这个程序是利用Young氏矩阵为n*n的数组排序。其中涉及到:插入法建立Young氏矩阵,然后再调用”去掉返回堆顶元素”的函数得到从小到大的排列。总的时间复杂度为O(n^3)。其中向Young氏矩阵“插入一个元素”的时间复杂度为O(m+n),m为Young氏矩阵的行数,n为Young氏矩阵的列数,建立Young氏矩阵要插入n*n个元素则为O((n^2)*2n)=O(n^3)。“去掉返回
2012-01-04 17:29:38 1567
原创 第六章堆排序之“对d叉堆的分析”(思考题6-2)
d叉堆在数组中如何表示:(1)若某个子节点索引为i,则它的父节点的索引为(i-2)/d+1,向下取整。(2)若某个父节点索引为i,则它的第j个子节点的索引为d*(i-1)+j+1。下面的程序是用插入法建立d叉最大堆,并显示了一次去掉和返回堆顶元素后剩余堆的情况。其中 “调整d叉堆” 的时间复杂度都为O(dlogd(n)),d为底哦。(纵向进行logd(n)(即深度)次,每次再横向比
2012-01-04 11:20:47 2885
原创 第六章堆排序之“插入法建堆”(思考题6-1)
建堆既可以用堆调整方法将原数组调整为一个堆,也可以借助往堆中插入元素的方法从无到有的建立一个堆。两种方法比较:(1)借助堆调整建堆的时间复杂度为O(n)。借助插入法建堆的时间复杂度为O(nlgn) ,书上第二问要求证明这个复杂度,但是我认为插入法的复杂度也是O(n),因为它和堆调整的区别在于针对每个节点i,堆调整是自上向下进行调整,插入法是自下向上进行调整。(2)对于同样的输入两个方法
2012-01-04 09:50:39 3746
原创 第六章堆排序之“用最小堆将k个已排序链表合并为一个排序链表”(练习6.5-8)
问题:请给出一个时间为O(nlgk),用来将k个已排序链表合并为一个排序链表的算法。此处的n为所有输入链表中元素的总数。(提示:用一个最小堆来做k路合并)编程思路:假设k个链表都是非降序排列的。(1)取k个元素建立最小堆,这k个元素分别是k个链表的第一个元素。建堆的时间复杂度O(k)。(2)堆顶元素就是k个链表中最小的那个元素,取出它。时间复杂度O(1)。(3)若堆顶元素所在链
2012-01-04 08:33:08 3631 3
原创 “作为函数参数的二维数组”即“怎么给函数传二维数组的指针”
刚才在百度知道看到了这个问题,回答了下,这个问题很好,总结一下。声明一个二维数组int matrix[100][100];当把二维数组作为参数传递的时候很多人可能一上来就这样写intfun(int **matrix),这样写是没有区分“指向整型指针的指针”与“指向整型数组的指针”的区别。这样传参是错的,因为matrix是个二维数组,matrix[100][100]是个二维
2012-01-03 18:54:13 10818
原创 第六章堆排序之“删除最大堆中的指定元素HEAP-DELETE”(练习6.5-7)
题目:HEAP-DELETE(A,i)操作将节点i中的项从堆中删去。对含n个元素的最大堆,请给出时间为O(lgn)的HEAP-DELETE的实现。编程思路:我们可以用堆中最后一个元素a[heapSize]放到节点i 位置,然后将heapSize减一。然后就涉及到堆调整以保持堆的性质。调整的依据就是这最后一个元素a[heapSize]跟原来i节点的元素a[i]的相对大小,分三种情况:
2012-01-03 14:32:57 6277
原创 第六章堆排序之“优先级队列实现先进先出队列和栈”(练习6.5-6)
这个不写代码了。思路如下:首先要先明确优先级是谁?优先级队列嘛,当然最重要的是要先知道“优先级”是谁,才能按它排序。这里的优先级就是进出队的次序。(1)优先级队列实现先进先出队列先进队的优先级更高,赋予每个进队的元素一个优先级值,但优先级的值我们令0最大,1次之,2再次之,···,然后按着这个优先级值建立最大优先级队列,每次用HeapExtractMax()取堆顶元素,这个肯定
2012-01-03 11:52:59 3777
原创 第六章堆排序之“最小优先级队列”(练习6.5-3)
用最小堆实现最小优先级队列://返回堆中关键字最小的元素HeapMinimum()//去掉并返回堆中关键字最小的元素HeapExtractMin()//将堆中元素x的关键字减小到k,k要小于x原来的关键字值HeapDecreaseKey()//将元素x插入到堆中MInHeapInsert()#include #include #include
2012-01-03 10:39:43 1061
原创 第六章堆排序之“最大优先级队列”
用最大堆实现最大优先级队列://返回堆的最大值int HeapMaximum(int *a)//去掉并返回堆中具有最大关键字的元素int HeapExtractMax(int *a,int *heapSize)//将元素x的关键字值增加到k,这里k不能小于x的原关键字值void HeapIncreaseKey(int *a,int i,int k)//将元素x插入到堆中
2012-01-02 22:01:38 915
原创 第六章堆排序之“堆排序HEAPSORT”
(1)先用BuildMaxHeap()建立最大堆(2)交换a[1]和a[heapSize],把最大的换到最后(3)堆大小heapSize减1(4)因为将最后一个元素换到堆顶可能会破坏堆的性质,所以调用MaxHeapIfy()将新的heapSize大小的堆调整最大堆(5)将(2)~(4)重复heapSize-1次,这里的heapSize是最初的那个heapSize。因为一共有heap
2012-01-02 19:45:59 925
原创 第六章堆排序之“建堆BUILD-MAX-HEAP”(迭代版)
自下向上对每一个结点或者只对每个非叶结点使用“保持堆的性质”即“堆调整”MAX-HEAPIFY#include #include #include #define BUFFER_SIZE 10void MaxHeapIfy(int *a,int i,int heapSize){ int left=i; int right=i; int tmp; int largest
2012-01-02 16:00:38 2756
原创 第六章堆排序之“建堆BUILD-MAX-HEAP”(递归版)
自下向上对每一个结点或者只对每个非叶结点使用“保持堆的性质”即“堆调整”MAX-HEAPIFY#include #include #include #define BUFFER_SIZE 10void MaxHeapIfy(int *a,int i,int heapSize){ int left=i<<1; int right=(i<<1)+1; int tmp
2012-01-02 15:58:12 1515
Bresenham画线算法、Cohen-SutherLand裁剪算法、de Casteljaus算法绘制贝赛尔曲线、扫描线填充算法、椭圆的扫描转换算法之C#实现
2012-09-01
Apriori和FP-Tree算法图形化实现+两个测试数据
2012-04-29
SETM算法代码+测试用例+具体操作步骤
2012-04-29
定时关机小程式(vc6实现,c语言)
2010-05-15
高精度模板c++高精度模板,c++实现,欢迎下载
2009-12-07
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人