#include <stdio.h> #define N 100 //子函数实现二分搜索算法,查找给定元素 x 的位置 int Binary_Search(int a[],int low,int high,int x) { int mid; mid=(low+high)/2; if(low>high) return -1; /*查找失败*/ else if(x==a[mid]) return mid; /*找到元素的位置并返回*/ else if(x>a[mid]) return Binary_Search(a,mid+1,high,x); else return Binary_Search(a,low,mid-1,x); } void main() { int a[N]; int i,t,x,n; printf("请输入已排序数组中元素的个数 n:"); scanf("%d",&n); printf("请输入已排序数组中的元素(共%d 个数):\n",n); for(i=0;i<n;i++) { scanf("%d",&a[i]); /*从键盘输入一组数*/ } printf("请输入要查找的元素 x 为:"); scanf("%d",&x); t=Binary_Search(a,0,n-1,x); /*调用子函数,查找元素 x 在数组 a[n]中的位置*/ if (t==-1) printf("\n 查找失败!"); else printf("元素 x 是数组中第%d 个元素。\n",t+1); /*因为数组的下标从 0 开始,实际的位置应为其坐标位置加 1*/ }
#include <stdio.h> #include <stdlib.h> #define N 8 //将两个有序的数组 R[low...m]和 R[m+1...high]归并成一个有序的数组 R[low..high] void Merge(int R[],int b[],int low,int m,int high) { int i=low,j=m+1,p=0; while(i<=m&&j<=high) /*两子数组非空时取其小者输出到 R1[p]上*/ b[p++]=(R[i]<=R[j])?R[i++]:R[j++]; while(i<=m) /*若第 1 个子文件非空,则复制剩余记录到 R1 中*/ b[p++]=R[i++]; while(j<=high) /*若第 2 个子文件非空,则复制剩余记录到 R1 中*/ b[p++]=R[j++]; for(p=0,i=low;i<=high;p++,i++) R[i]=b[p]; /*归并完成后将结果复制回 R[low..high]*/ } //用分治法对 R[low..high]进行二路归并排序 void MergeSort(int R[],int low,int high) { int mid; int b[N]; if(low<high) /*区间长度大于 1*/ { mid=(low+high)/2; /*分解*/ MergeSort(R,low,mid); /*递归地对 R[low..mid]排序*/ MergeSort(R,mid+1,high); /*递归地对 R[mid+1..high]排序*/ Merge(R,b,low,mid,high); /*组合,将两个有序区归并为一个有序区*/ } } void main() { int a[N]; int i,j; for(j=0;j<N;j++) a[j]=rand()%100; /*系统随机生成 8 个数*/ //scanf("%d",&array[j]); //取消此注释语句可以手动输入无序数组 printf("随机生成数组为:\n"); for(i=0;i<N;i++) printf("%d ",a[i]); MergeSort(a,0,N-1); printf("\n 已排序数组为:\n"); for(i=0;i<N-1;i++) printf("%d ",a[i]); printf("\n\n"); }
Between years 5 and 8 ACME earned 5 + 2 − 1 + 3 = 9 Million Dollars
This is the MAXIMUM amount that ACME earned in any contiguous span of years.
Examples: Between years 1 and 9 ACME earned −3 + 2 + 1 − 4 + 5 + 2 − 1 + 3 − 1 = 4 and between years 2 and 6 2 + 1 − 4 + 5 + 2 = 6
The Maximum Contiguous Subarray Problem is to find the span of years in which ACME earned the most, e.g., (5, 8).
Idea: Calculate the value of V (i, j) for each pair i ≤ j and return the maximum value.
VMAX=A[1]; for (i=1 to N) { for (j=i to N) { // calculate V(i, j) V=0; for (x= i to j) V=V+A[x]; if (V > VMAX) VMAX=V; } } return VMAX;
Idea: We don’t need to calculate each V (i, j) from “scratch” but can exploit the fact that
VMAX=A[1]; for (i=1 to N) { V=0; for (j=i to N) { // calculate V(i, j) V=V+A[j]; if (V > VMAX) VMAX=V; } } return VMAX;
Idea: Set M = [(N + 1)/2] , [] indicates rounding down temporarily.
Let A1 and A2 be the MCS that must contain A[M] and A[M + 1] respectively. Note that the MCS must be one of
MAX=A[M]; SUM=A[M]; for (k=M-1 down to i) { SUM+=A[k]; if (SUM > MAX) MAX=SUM; } A_1=MAX;
// Input : A[i . . . j] with i ≤ j
// Output : the MCS of A[i . . . j]
Let T(m) (where m is the problem size) be time needed to run
MCS(A, i, j), (j − i + 1 = m)
Step (1) requires O(1) time.
Steps (3) and (4) each require T(m/2) time.
Step (5) requires O(m) time.
Step (6) requires O(1) time
Then T(1) = O(1) and for n > 1, T(n) = 2 T(n/2) + O(n)
To simplify the analysis, we assume that n is a power of 2.
T(n) ≤ 2 T( n 2 ) + c n.
Repeating this recurrence gives
Set h = log2 n, so that 2 h = n.
With this substitution, we have
In this lecture we saw 3 different algorithms for solving the maximum contiguous subarray problem. They were