这个程序使用分治法计算最大子段,结果为最大子段之和,用递归程序实现。
原始数据使用随机函数生成。
采用结构化程序设计,可以很容易改为从标准输入或文件读入数据,只需要修改函数getData即可。
数据个数由宏定义给出,也可以轻松地改为输入。
/* * 最大子段算法程序 */ #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 13 void getData(int [], int); int maxsumfun(int a[], int left, int right); int main(void) { int a[N], i; getData(a, N); /* 获得数据放入数组a中 */ printf("datas: "); for (i = 0; i < N; i++) printf("%d ", a[i]); printf("\n"); int ms; ms = maxsumfun(a, 0, N - 1); printf("maxsum=%d\n", ms); return 0; } int maxsumfun(int a[], int left, int right) { int maxsum = 0; if(left == right) { if(a[left] > 0) maxsum = a[left]; else maxsum = 0; } else { int mid, leftsum, rightsum, midsum; mid = (left + right) / 2; leftsum = maxsumfun(a, left, mid); rightsum = maxsumfun(a, mid+1, right); int leftsum1 = 0; int lefts = 0; int i; for(i=mid; i>=left; i--) { lefts += a[i]; if(lefts > leftsum1) leftsum1 = lefts; } int rightsum1 = 0; int rights = 0; for(i=mid+1; i<=right; i++) { rights += a[i]; if(rights > rightsum1) rightsum1 = rights; } midsum = leftsum1 + rightsum1; if(midsum < leftsum) maxsum = leftsum; else maxsum = midsum; if(maxsum < rightsum) maxsum = rightsum; } return maxsum; } void getData(int d[], int n) { time_t t; srand((unsigned) time(&t)); /* 设置随机数起始值 */ int i; for(i=0; i < n; i++) d[i] = rand() % 30 - 10; /* 获得-10--20之间的整数值 */ }
关键代码:
// 递归计算最大子段 int maxsumfun(int a[], int left, int right) { int maxsum = 0; if(left == right) { if(a[left] > 0) maxsum = a[left]; else maxsum = 0; } else { int mid, leftsum, rightsum, midsum; mid = (left + right) / 2; leftsum = maxsumfun(a, left, mid); rightsum = maxsumfun(a, mid+1, right); int leftsum1 = 0; int lefts = 0; int i; for(i=mid; i>=left; i--) { lefts += a[i]; if(lefts > leftsum1) leftsum1 = lefts; } int rightsum1 = 0; int rights = 0; for(i=mid+1; i<=right; i++) { rights += a[i]; if(rights > rightsum1) rightsum1 = rights; } midsum = leftsum1 + rightsum1; if(midsum < leftsum) maxsum = leftsum; else maxsum = midsum; if(maxsum < rightsum) maxsum = rightsum; } return maxsum; }