从今天开始,算是正式踏入学习数据结构了。然而,第0课就差点被劝退,最大子列和问题中的分治法,我估计不对着书本,我是写不出的,算法理解上没问题,但一旦碰到递归,我就很难理解代码的意思,相反,在线算法就很好理解,也很好写成代码。
#include <stdio.h>
#include <stdlib.h>
int MaxSubsequence(int list[], int len);
int MaxSubsequenceDC(int list[], int len);
int maxOfThree(int a, int b, int c);
int DivideAndConquer(int list[], int left, int right);
int MaxSubsequenceOL(int list[], int len);
int main()
{
int k, i, max, max1, max2;
scanf("%d",&k);
int a[k];
for(i=0; i<k; i++)
{
scanf("%d", &a[i]);
}
max = MaxSubsequence(a, k);
max1 = MaxSubsequenceDC(a, k);
max2 = MaxSubsequenceOL(a, k);
printf("ORI:%d\n", max);
printf("DC:%d\n", max1);
printf("OL:%d\n", max2);
system("pause");
}
int MaxSubsequence(int list[], int len)
{
int i, j;
int thisSum, maxSum=0;
for(i=0; i<len; i++)
{
thisSum = 0;
for(j=i; j<len; j++)
{
thisSum += list[j];
if(thisSum>maxSum)
{
maxSum = thisSum;
}
}
}
return maxSum;
}
int MaxSubsequenceDC(int list[], int len)
{
return DivideAndConquer( list, 0, len-1);
}
int maxOfThree(int a, int b, int c)
{
return a>b?a>c?a:c:b>c?b:c;
}
int DivideAndConquer(int list[], int left, int right)
{
int i;
int center, maxLeft, maxRight;
int leftBorderSum, rightBorderSum, maxLeftBorderSum, maxRightBorderSum;
if(left == right)
{
if(list[left]>0)
return list[left];
else
return 0;
}
center = (left+right)/2;
/**< 通过不断迭代,最底层是一个数字,然后就可以直接返回左列或者右列(唯一一个数字)最大值 */
maxLeft = DivideAndConquer(list, left, center);
maxRight = DivideAndConquer(list, center+1, right);
leftBorderSum = maxLeftBorderSum = 0;
for(i=center; i>=left; i--)
{
leftBorderSum += list[i];
if(leftBorderSum>maxLeftBorderSum)
maxLeftBorderSum = leftBorderSum;
}
rightBorderSum = maxRightBorderSum = 0;
for(i=center+1; i<=right; i++)
{
rightBorderSum += list[i];
if(rightBorderSum>maxRightBorderSum)
maxRightBorderSum = rightBorderSum;
}
return maxOfThree(maxLeft, maxRight, maxLeftBorderSum+maxRightBorderSum);
}
int MaxSubsequenceOL(int list[], int len)
{
int i;
int thisSum = 0;
int maxSum = 0;
for(i=0; i<len; i++)
{
thisSum += list[i];
if(thisSum>maxSum)
maxSum = thisSum;
if(thisSum<0)
thisSum = 0;
}
return maxSum;
}