《数据结构与算法分析》第二章,最大子序列求和递归看不懂。。。

privilege1900 2013-03-21 12:00:48
这本书很多人应该都看过。其实很早之前我就尝试着看这本书,只是这个最大子序列求和的递归
算法实在看不懂,然后就先不看。没想到过了这么久,现在还是看不懂

惯例先贴代码

#include <stdio.h>

/*求三个整数中最大的数*/
int Max(int a, int b, int c) {
int max = 0;
if (a > b)
max = a;
else
max = b;

if (max > c)
return max;
else
return c;
}

/*参数Left和Right分别为传入数组的左右边界*/
int MaxSubSum(const int A[], int Left, int Right) {
int MaxLeftSum, MaxRightSum; /*将数组分为左右两半后,左边和右边的子序列最大值*/
int MaxLeftBorderSum, MaxRightBorderSum;
int LeftBorderSum, RightBorderSum;
int Center, i;

if (Left == Right)
{
if (A[Left] > 0)
return A[Left];
else
return 0;
}

/*递归算法开始,好吧,我看不懂...*/
Center = (Left + Right) / 2;
MaxLeftSum = MaxSubSum(A, Left, Center);
MaxRightSum = MaxSubSum(A, Center + 1, Right);

MaxLeftBorderSum = 0;
LeftBorderSum = 0;

for (i = Center; i >= Left; i--)
{
LeftBorderSum += A[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}

MaxRightBorderSum = 0;
RightBorderSum = 0;

for (i = Center + 1; i <= Right; i++)
{
RightBorderSum += A[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}

return Max(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
}

/*Main函数输出最终结果,无实意*/
int main(int argc, char * argv[])
{
int array[10] = { 4, -3, 12, 9, -7, 15, -16, 2, 8, -1 };
int max = MaxSubSum(array, 0, 9);
printf("What...\n");
printf("max = %d" , max);
}


对于这三行核心代码,我是真不明白到底怎么运行的,画图后更糊涂了。。。

Center = (Left + Right) / 2;
MaxLeftSum = MaxSubSum(A, Left, Center);
MaxRightSum = MaxSubSum(A, Center + 1, Right);



好吧,假设现在只传五个数的数组 int array[] = { 12, 3, 5, 6, -1 },
调用MaxSubSum(array, 0, 4)
第一次执行到递归代码时,是酱紫:

Center = 2;
MaxLeftSum = MaxSubSum(array, 0, 2);

进入递归 ---------(第一层递归) Left = 0, Right = 2
第二次执行到递归代码时:

Center = 1;
MaxLeftSum = MaxSubSum(array, 0, 1);

进入下一层递归---------(第二层递归) Left = 0, Right = 1
第三次执行时:

Center = 0;
MaxLeftSum = MaxSubSum(array, 0, 0);

进入下一层递归---------(第三层递归) Left = 0, Right =0
终于Left == Right了, 于是return array[0];

返回第二层递归,执行下一条语句:

MaxRightSum = MaxSubSum(array, 0, 1);


这尼玛。。。 不是又重复了一遍么。这到底什么意思,我表示大脑空间溢出了。。。
我也没看到递归里有加法运算哪,最后怎么就得出了左右两半数组的最大子序列和?
小弟分少,哎,就意思意思吧。
好吧,我弱爆了,求大神指点迷津啊,老衲法号戒撸
...全文
330 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
luck2donkey 2014-10-19
  • 打赏
  • 举报
回复
楼主怎么解决的
luck2donkey 2014-10-19
  • 打赏
  • 举报
回复
我也看到这里卡主了
abnerwang_smile 2014-07-01
  • 打赏
  • 举报
回复
见我的博客:http://blog.csdn.net/abnerwang2014/article/details/36027747
privilege1900 2013-03-21
  • 打赏
  • 举报
回复
嘁,真是失望啊,都是只会说说而已么?没一个人敢稍微分析下这段代码么, 我文字里最明显的错误是最后贴的那段代码
MaxRightSum = MaxSubSum(array, 0, 1); 
应该是
MaxRightSum = MaxSubSum(array, 1, 1); 
这种错误都没发现,看来根本没人愿意耐心帮忙解决问题。结贴吧。
赵4老师 2013-03-21
  • 打赏
  • 举报
回复
“给定一个小点的输入,完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门! 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出
_sunshine 2013-03-21
  • 打赏
  • 举报
回复
楼主还是没有理解递归的核心思想,楼主再仔细研究下递归应该就会明白,上面这个例子很经典,还有汉诺塔。求最长子序列,不一定要用到加法,而是Max(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum)

70,026

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧