算法导论第三版 练手程序C++(第二章)(2)
2014-11-16 21:03
411 查看
实在闲的蛋疼,大神不要喷我
第二章
分治法排序:
伪代码:MERGE(A,p,q,r) n1 = q-p+1 n2 = r-q 新建数组 L[1..n1+1] 和 R[1..n2+1] for i = 1 to n1 L[i] = A[p+i-1] forj = 1 to n2 R[j] = A[q+j] L[n1+1] = NaN R[n2+1] = NaN i = 1 j = 1 for k = p to r if L[i]<=R[j] A[k] = L[i] i = j+1 else A[k] = R[j] j = j+1 MERGE-SORT(A,p,r) if p<r q = |_(p+r)/2_| MERGE-SORT(A,p,q) MERGE-SORT(A,q+1,r) MERGE(A,p,q,r)
这里有个蛋疼的问题,伪代码里,L和R每次调用merge时都是new出来(对C++而言)的,但是,要知道new一个数组画得时间远大于一般的计算,更不必说还要把new出来的数组delete掉了,那么咋办呢。。只好实现就新建一个全局的数组(类似缓存区的功能),每次需要新的数组时,直接利用全局数组,而merge里所需的数组的大小必然小于需要排序的数组的大小,那么,就创建一个和待排序数组大小一样的全局数组吧。
#include <stdlib.h> #include <time.h> #include <iostream> #define PAI_LENGTH 10000 using namespace std; int cache[PAI_LENGTH+2]; void merge(int A[],int p,int q,int r) { int i,j; int n1 = q-p+1; int n2 = r-q; int *L = cache; int *R = cache+n1+1; for(i = 0;i<n1;i++) { L[i] = A[p+i]; } for(j=0;j<n2;j++) { R[j] = A[q+j+1]; } L[n1] = 10000; R[n2] = 10000; i=0; j=0; for(int k=p;k<=r;k++) { if(L[i]<=R[j]) { A[k] = L[i]; i++; }else{ A[k] = R[j]; j++; } } } void merge_sort(int A[],int p,int r) { if(p<r) { int q = (p+r)/2; merge_sort(A,p,q); merge_sort(A,q+1,r); merge(A,p,q,r); } } void printAll(int A[],int length) { for(int i=0;i<length;i++) { cout<<A[i]<<endl; } } int main() { clock_t start,end; int raw[PAI_LENGTH]; srand((unsigned)time(NULL)); for(int i=0;i<PAI_LENGTH;i++) { raw[i] = rand()%10000+1; } start = clock(); merge_sort(raw,0,PAI_LENGTH-1); end = clock(); cout<<"use"<<(end-start)<<"us"<<endl; }嗯,对,又是直接一大片代码。。其实看过上一篇的可以发现mian函数大部分的代码是在创建随机数组和计时的,看看结果:
use 4243 us
还有谁!!!同样10000个随机数,为什么分治算法这么快呢,没错,你没有看错,答案将会在第3,4章揭晓。。。。
下面顺便分享一下习题2.3-2的做法。要求是重写merge函数,使之不使用哨兵排,所以伪代码变成下面的样子:
MERGE(A,p,q,r) n1 = q-p+1 n2 = r-q let L[1..n1] and R[1..n2] be new arrays for i = 1 to n1 L[i] = A[p+i-1] forj = 1 to n2 R[j] = A[q+j] i = 1 j = 1 k=p while i<=n1 and j<=n2 if L[i]<=R[j] A[k] = L[i] i = j+1 else A[k] = R[j] j = j+1 k++ if i<=n1 for k=k to r A[k]=R[j] j=j+1 else for k=k to r A[k]=L[i] i=i+1 MERGE-SORT(A,p,r) if p<r q = |_(p+r)/2_| MERGE-SORT(A,p,q) MERGE-SORT(A,q+1,r) MERGE(A,p,q,r)
恩好像没差嘛。看看对应的程序:
#include <stdlib.h> #include <time.h> #include <iostream> #define PAI_LENGTH 10000 using namespace std; int cache[PAI_LENGTH+2]; void merge(int A[],int p,int q,int r) { int i,j; int n1 = q-p+1; int n2 = r-q; int *L = cache; int *R = cache+n1; for(i = 0;i<n1;i++) { L[i] = A[p+i]; } for(j = 0;j<n2;j++) { R[j] = A[q+j+1]; } i=0; j=0; int k=p; for(;i<n1&&j<n2;k++) { if(L[i]<=R[j]) { A[k] = L[i]; i++; }else{ A[k] = R[j]; j++; } } if(i>=n1) { for(;k<=r;k++) { A[k] = R[j]; j++; } }else{ for(;k<=r;k++) { A[k] = L[i]; i++; } } } void merge_sort(int A[],int p,int r) { if(p<r) { int q = (p+r)/2; merge_sort(A,p,q); merge_sort(A,q+1,r); merge(A,p,q,r); } } void printAll(int A[],int length) { for(int i=0;i<length;i++) { cout<<A[i]<<endl; } } int main() { clock_t start,end; int raw[PAI_LENGTH]; srand((unsigned)time(NULL)); for(int i=0;i<PAI_LENGTH;i++) { raw[i] = rand()%10000+1; } start = clock(); merge_sort(raw,0,PAI_LENGTH-1); end = clock(); printAll(raw,PAI_LENGTH); cout<<"use"<<(end-start)<<"us"<<endl; }
恩,好像也没差嘛。。。
再看看运行结果:
use 4297 us
恩,果然没差。。
相关文章推荐
- 算法导论第三版 练手程序C++(第二章)(1)
- C++练手小程序 整数幂的计算
- 算法导论第三版第二章第三节习题答案
- 第二章 从一个最简短的C++程序讲起
- C++程序设计(第二版)谭浩强----程序题课后习题答案第二章
- Effective C++:改善程序技术与设计思维的55个有效做法(第三版)(中文版)(预订)Effective C++ 3RD
- 算法导论(第三版) 第二章思考题
- 算法导论(第三版) 第二章练习题
- 算法导论第三版第二章思考题答案
- 算法导论第三版 第二章 2.3-7
- C_PlusPlus学习笔记 - 4_C++程序结构 (C++语言程序设计【第三版】 郑莉等,清华大学出版社)
- C++对象模型——程序转化语意学(第二章)
- 小程序练手(c++)
- 算法导论第三版第二章第二节习题答案
- 第二章 做一个简短的C++程序
- 算法导论第二章C++实现归并算法排序
- 算法导论中LCS的C++实现程序
- 算法导论第二章mergesort的C++ 实现
- 数据结构与算法分析(C++第三版)第二章问题总结
- 算法导论第12章-搜索二叉树伪代码的C++程序全实现