常用算法设计技巧
来源:互联网 发布:php会员信息管理系统 编辑:程序博客网 时间:2024/05/04 14:39
1.贪心算法
实例:Dijkstra算法,Prim算法,Kruskal算法,调度(最小化平均完成时间),哈夫曼编码,装箱算法
哈夫曼编码采用最小堆实现时,运行时间为O(C log C),采用简单链表为O(C^2)。在ASCII字符集的情况下,C足够小,这使得二次时间可以接受,这样的应用中实际上所有的运行时间都将花费在读进输入文件和写出压缩文件所需要的磁盘I/O上。
2.分治算法
实例:最大子序列和,平面几何最近点,树递归遍历,归并排序,快速排序,快速选择
分治算法的运行时间方程可归结为 : T(N)=aT(N/b)+Θ(N^k)。
最近点问题可将点集按照x坐标和y坐标排序,将点集按x分为两半,PL和PR,分别计算dL、dR和dC,dC时间为O(N),因此总时间为O(NlogN)。
整数相乘(两个八位整数X,Y)常规是O(N^2)。
有4次相乘,将问题缩小为(N/2)。四次相乘可以减少为3次:
由此,T(N)=3T(N/2)+O(N)=O(N^1.59)。
矩阵乘法常规为Ω(N^3),代码如下。
matrix<int> operator*(const matrix<int>& a,const matrix<int>& b){ int n=a.numrows(); matrix<int> c(n,n); int i; for(i=0;i<n;i++) for(int j=0;j<n;j++) c[i][j]=0; for(i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) c[i][j]+=a[i][k]*b[k][j]; return c;}可采用Strassen方法降阶。
3.动态规划
实例:用表代替递归,矩阵乘法的顺序安排,最优二叉查找树,有向图中所有点对最短路径(稠密图)
将递归算法重新写成非递归算法,可以把子问题的答案系统地记录在一个表中,利用这种方法的一种技巧称为动态规划。
计算fibonacci数列的递归和动态规划代码:
int fib(int n){ if(n<=1) return 1; else return fib(n-1)+fib(n-2);}int fibonacci(int n){ if(n<=1) return 1; int last=1; int nextToLast=1; int answer=1; for(int i=2;i<=n;i++) { answer=last+nextToLast; nextToLast=last; last=answer; } return answer;}最优二叉查找树公式如下O(N^3),可优化为O(N^2):
所有点对最短路径(稠密图)公式O(N^3):
,
代码:
void allPairs(matrix<int>& a,matrix<int>& d,matrix<int>& path){ int n=a.numrows(); //initialize d and path for(int i=0;i<n;i++) for(int j=0;j<n;j++) { d[i][j]=a[i][j]; path[i][j]=-1; } for(int k=0;k<n;k++) //consider each vertex as an intermediate for(int i=0;i<n;i++) for(int j=0;j<n;j++) if(d[i][k]+d[k][j]<d[i][j]) { //update shortest path d[i][j]=d[i][k]+d[k][j]; path[i][j]=k; }}
4.随机化算法
实例:跳跃表,随机素性测试
生成随机数的代码:
static const int A=48271;static const int M=2147483647;//2^31-1static const int Q=M/A;static const int R=M%A;class Random{public: explicit Random(int initialValue=1); int randomInt(); double random0_1(); int randomInt(int low,int high);private: int state;};//Construct with initialValue for stateRandom::Random(int initialValue){ if(initialValue<0) initialValue+=M; state=initialValue; if(state==0) state=1;}//period M-1int Random::randomInt(){ int tmpState=A*(state%Q)-R*(state/Q); if(tmpState>=0) state=tmpState; else state=tmpState+M; return state;}double Random::random0_1(){ return (double)randomInt()/M;}int Random::randomInt(int low,int high){ if(low>high) return -1; return randomInt()%(high-low+1)+low;}跳跃表:以O(logN)期望支持查找和插入。
素性测试:随机化方法极快,偶尔会出现错误的判断,但这种机会非常小,足可忽略。
5.回溯算法
实例:公路收费点重建问题(O(N^2 * logN)),博弈(极大极小策略,α-β裁剪)
- 常用算法设计技巧
- 【算法】算法设计技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- Web设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网站设计常用技巧
- 网页设计常用技巧
- 常用页面设计技巧
- PCB 常用设计技巧
- 常用网站设计常用技巧
- C++算法设计技巧
- 算法设计技巧
- linux中提供了PF_PACKET接口可以操作链路层的数据
- 大话数据结构开篇:时间复杂度和空间复杂度
- UVA 10236 The Fibonacci Primes
- make传递给Makefile参数
- 才高行厚的hibernate(3)---对象状态&常用接口
- 常用算法设计技巧
- struts整合spring
- Cheapest Palindrome 简单dp
- MYSQL子查询的五种形式
- openflow
- 对Android四大组件的理解(转自百度知道)
- C++动态库导出函数及变量,没整理
- KL距离,Kullback-Leibler Divergence
- Ubuntu13.10安装Sublime Text