数据是稳定的(即不允许插入操作和删除操作)
在任意时刻,算法都能对它已经读入的数据给出子序列问题的答案,具有这种特性的算法叫做联机算法(online algorithm)
分治(divide-and-conquer)策略:其想法是把问题分成两个大致相等的子问题,然后递归地对他们求解,这是“分”部分。“治”阶段将两个子问题的解合并到一起并可能再做些少量的附加工作,最后得到整个问题的解。
当编写递归例程的时候,关键是要牢记递归地四条基本法则:
基准情形。 某些基准情形,无须递归就能解出
不断推进。 每次递归都必须使求解状况朝基准情形推进
设计法则。 假设所有的递归调用都能运行
合成效益法则(compound interest rule)。在求解一个问题的同一个实例时,切勿在不同的递归调用中做重复性的工作
如果一个算法用常数时间(O(1))将问题的大小削减为其一部分(通常是1/2),那么该算法就是O(logN)。 另一方面,如果使用常数时间只是把问题减少一个常数(如将问题减少1),那么这种算法就是O(N)的。
程序1:输出数组中第K大的数
#include<stdio.h> #define SIZE 100 int main() { int i,j,k,t,n,num[SIZE],tmp[SIZE]; //the original array num as follows printf("please input the array size(n) : "); scanf("%d",&n); printf("please input the array(including %d integer) :\n",n); for(i=0;i<n;++i) { scanf("%d",&num[i]); } //output the kth number in num printf("please input the number k(rank k'th in the descending order array):"); scanf("%d",&k); tmp[0]=num[0]; //put the number num[i] into tmp[t],in tmp,the order is descending for(i=1;i<k;++i) { for(j=i-1;j>=0;--j) { if(num[i]<=tmp[j]) { break; } else { tmp[j+1]=tmp[j]; } } t=j+1; tmp[t]=num[i]; } //insert num[i] into tmp[j+1] when num[i]>tmp[k] for(i=k;i<n;++i) { for(j=k-1;j>=0;--j) { if(num[i]<=tmp[j]) break; else tmp[j+1]=tmp[j]; } if(j+1<=k-1) { tmp[j+1]=num[i]; } } printf("Following the descending order,the %dth number is : %d\n",k,tmp[k-1]); return 0; }
程序2:输出文件中的全部数据
#include<stdio.h> #include<stdlib.h> int main() { FILE *fp=fopen("/usr/include/stdio.h","r+"); char* buffer=malloc(sizeof(char)*65535); if(fp==NULL) { printf("fp is NULL"); return 0; } while(fread(buffer,sizeof(char),65535,fp)!=0) { printf("%s",buffer); } printf("\n"); fclose(fp); return 0; }
程序3:输出最大子序列和。以下3个算法,数据量很大时,运行时间递减
算法1:
#include<stdio.h> #define SIZE 10 int main() { int num[SIZE]; int i,j; int tmp,sum=0; int start=0,end=0; printf("please input the element of the array[%d] :\n",SIZE); for(i=0;i<SIZE;++i) scanf("%d",&num[i]); for(i=0;i<SIZE;++i) { tmp=0; for(j=i;j<SIZE;++j) { tmp+=num[j]; if(sum<tmp) { start=i; sum=tmp; end=j; } } } printf("the max_sublist_sum is %d\n",sum); for(i=start;i<end;++i) printf("%d ",num[i]); printf("%d\n",num[end]); return 0; }
算法2:
#include<stdio.h> #define SIZE 10 int maxsubsum(int array[],int left,int right) { int maxleftsum,maxrightsum,maxcentersum; int maxleftbordersum=0,maxrightbordersum=0; int leftbordersum=0,rightbordersum=0; int center,i; if(left==right) if(array[left]>0) return array[left]; else return 0; center=(left+right)/2; maxleftsum=maxsubsum(array,left,center); maxrightsum=maxsubsum(array,center+1,right); for(i=center;i>=left;--i) { leftbordersum+=array[i]; if(maxleftbordersum<leftbordersum) maxleftbordersum=leftbordersum; } for(i=center+1;i<=right;++i) { rightbordersum+=array[i]; if(maxrightbordersum<rightbordersum) maxrightbordersum=rightbordersum; } maxcentersum=maxrightbordersum+maxleftbordersum; return maxleftsum>maxrightsum?(maxleftsum>maxcentersum?maxleftsum:maxcentersum):(maxrightsum>maxcentersum?maxrightsum:maxcentersum); } int main() { int array[SIZE],left=0,right=SIZE-1,i; printf("please input the element of the array[%d] :\n",SIZE); for(i=0;i<SIZE;++i) { scanf("%d",&array[i]); } printf("the max_sublist_sum is : %d\n",maxsubsum(array,left,right)); /* for(i=left;i<right;++i) printf("%d ",array[i]); printf("%d\n",array[right]); */ return 0; }
算法3:
#include<stdio.h> #define SIZE 10 int main() { int thissum=0,maxsum=0,i; int array[SIZE]; printf("please input the element of the array[%d] :\n",SIZE); for(i=0;i<SIZE;++i) { scanf("%d",&array[i]); } for(i=0;i<SIZE;++i) { thissum+=array[i]; if(thissum>maxsum) maxsum=thissum; else if(thissum<0) thissum=0; } printf("the max_sublist_sum is : %d\n",maxsum); return 0; }
程序4:对分查找(binary search)
#include<stdio.h> #define SIZE 10 int main() { int array[SIZE],i,goal,left=0,right=SIZE-1,mid; printf("please input the element of the array[%d]:\n",SIZE); for(i=0;i<SIZE;++i) { scanf("%d",&array[i]); } printf("please input the goal :"); scanf("%d",&goal); while(left<=right) { mid=(left+right)/2; if(array[mid]>goal) right=mid-1; else if(array[mid]<goal) left=mid+1; else { printf("the index is : %d\n",mid); return 0; } } printf("not find the goal\n"); return 0; }
程序5:计算最大公因数的欧几里得算法
#include<stdio.h> Gcd(unsigned int M,unsigned int N) { unsigned int Rem; while(N>0) { Rem=M%N; M=N; N=Rem; } return M; } int main() { unsigned int M,N; printf("please input M and N :"); scanf("%d %d",&M,&N); printf("the Gcd is : %d\n",Gcd(M,N)); return 0; }
程序6:幂运算
#include<stdio.h> long int Pow(long int x,unsigned int N) { long int tmp; if(N==0) return 1; else if(N==1) return x; tmp=Pow(x*x,N/2); if(N%2!=0) tmp*=x; return tmp; } int main() { printf("please input the x and N: "); long int x; unsigned int N; scanf("%ld %u",&x,&N); printf("the result is :%ld\n",Pow(x,N)); return 0; }
程序7:计算两个随机选取出并小于或等于NN的互异正整数互素的概率
#include<stdio.h> #define NN 6 unsigned int Gcd(unsigned int M,unsigned int N) { unsigned int Rem; while(N>0) { Rem=M%N; M=N; N=Rem; } return M; } int main() { int Rel=0,Tot=0,j,i; for(i=1;i<=NN;++i) for(j=i+1;j<=NN;++j) { Tot++; if(Gcd(i,j)==1) Rel++; } printf("the probability of it that they are prime is :%f\n",(Rel+0.0)/Tot); return 0; }