第八章,作者通过对最大子段和问题的深入探讨,讲解了时间复杂度对算法设计的影响。在实际中,程序实现指定功能可能会有多种方法,此时我们考虑的不仅是功能的实现,还需要在功能实现的基础上考虑算法的时间复杂度。
在最大子段和的问题上,作者先后分析了四种实现方式,对其时间复杂度做了理论分析,并且对不同数量级的数据进行了实际运行时间的统计。通过这样一系列的介绍,作者总结了几个重要的算法设计技术:
1、保存状态,避免重复计算。(算法2和算法4)
2、将信息预处理至数据结构中。(算法2b)
3、分治算法。(算法3)
4、扫描算法。(算法4)
5、累计。(算法2b)
6、下界。
下面是几个算法的实现。
"h1.h"
#ifndef H1_H
#define H1_H
#include<string.h>
#include<ctype.h>
#include<time.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include<io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> /* exit() */
#define MAXSIZE 100
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
struct posNode{
int start;
int end;
};
#endif
"maxSum.cpp"
#include"h1.h"
//Solution 1, Time complexity is O(n^3)
int maxSum1(int a[], int n, posNode *pos){ //用start和end返回子向量,函数返回最大值和位置
int i, j, k;
int sum, maxsofar;
maxsofar = 0;
for(i=0; i<n; i++){
for(j=i; j<n; j++){
sum = 0;
for(k=i; k<j; k++){
sum = sum + a[k];
if(sum > maxsofar){
maxsofar = sum;
pos->start = i;
pos->end = k;
}
}
}
}
return maxsofar;
}
//Solution 2, Time complexity is O(n^2)
int maxSum2a(int a[], int n, posNode *pos){
int i, j;
int sum, maxsofar;
maxsofar = 0;
for(i=0; i<n; i++){
sum = 0;
for(j=i; j<n; j++){
sum = sum + a[j];
if(sum > maxsofar){
maxsofar = sum;
pos->start = i;
pos->end =j;
}
}
}
return maxsofar;
}
int maxSum2b(int a[], int n, posNode *pos){
int realarray[101];
int *cumarr;
int i, j, maxsofar, sum;
cumarr = realarray+1;
cumarr[-1] = 0;
for(i=0; i<n; i++){
cumarr[i] = cumarr[i-1] + a[i];
}
maxsofar = 0;
for(i=0; i<n; i++){
for(j=i; j<n; j++){
sum = cumarr[j] - cumarr[i];
if(sum > maxsofar){
maxsofar = sum;
pos->start = i+1;
pos->end = j;
}
}
}
return maxsofar;
}
//Solution3, Time complexity is O(nlogn)
int maxSum3(int a[], int low, int high, posNode *pos){
int i, m, lmax, rmax, max, leftPos, rightPos, sum;
if(low > high){
return 0;
}
if(low == high){
if(a[low] > 0){
return a[low];
}
else{
return 0;
}
}
m = (low+high) / 2;
leftPos = rightPos = m;
lmax = sum = 0;
for(i=m; i>=low; i--){
sum = sum + a[i];
if(sum > lmax){
lmax = sum;
leftPos = i;
}
}
rmax = sum = 0;
for(i=m+1; i<=high; i++){
sum += a[i];
if(sum > rmax){
rmax = sum;
rightPos = i;
}
}
max = maxSum3(a, low, m-1, pos);
if( maxSum3(a, m+1, high, pos) > max){
max = maxSum3(a, m+1, high, pos);
}
if(lmax+rmax > max){
max = lmax + rmax;
pos->start = leftPos;
pos->end = rightPos;
}
return max;
}
//Solution4, Time complexity is 0(n)
int maxSum4(int a[], int n, posNode *pos){
int maxSofar, maxEnding;
int i;
maxSofar = 0;
maxEnding = 0;
pos->start = 0;
pos->end = 0;
for(i=0; i<n; i++){
maxEnding += a[i];
if(maxEnding < 0){
maxEnding = 0;
pos->start = i+1;
}
if(maxSofar < maxEnding){
maxSofar = maxEnding;
pos->end = i;
}
}
return maxSofar;
}
int main(){
int a[]= {31, -41, 59, 26, -53, 58, 97, -93, -23, 84};
posNode *pos;
pos = (posNode*)malloc(sizeof(posNode));
if(!pos){
printf("Memory allocation error!\n");
exit(0);
}
pos->start = 0;
pos->end = 0;
long startClock, endClock;
startClock = clock();
int result = maxSum4(a, 10, pos);
endClock = clock();
printf("The result is:%d , The position starts at %d, ends at %d .\nThe time cost is %d \n",
result, pos->start+1, pos->end+1,endClock-startClock);
free(pos);
return 0;
}