关于递归问题求解

baoxiaofei123 2010-05-07 01:17:55
在网上见到一个归并排序的code:
/*include<stdio.h>.....*/
void merge(.....)
{
...../*具体就是对分割好的子数组排序,很简单。不写了*/
}

void merge_sort(int *a,int left,int right)
{
int half;
if(left<right)
{
half=(int)((left+right)/2);
merge_sort(a,left,half);/*这两条语句的执行过程是怎么样的?*/
merge_sort(a,half+1,right);
/*这条语句能执行?*/
merge(.....);/*具体排序函数*/
}
}
...全文
116 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
zwl327 2010-05-07
  • 打赏
  • 举报
回复
从整体上去理解:
函数的意思就是:
先从中间
half=(int)((left+right)/2);//从中间分成两半
merge_sort(a,left,half);/*排左边一半*/
merge_sort(a,half+1,right); /*排右边一半*/
merge(.....);/*合并*/

然后左边和右边的一半也会这么排下去.
Rider628 2010-05-07
  • 打赏
  • 举报
回复
给分!!!!!
Rider628 2010-05-07
  • 打赏
  • 举报
回复
这个日志好看点
21 63 13 41 54 61
Left0 21
Right0 63
a0 21 a1 63
Left0 21 Left1 63
Right0 13
a0 13 a1 -842150451 a2 21
Left0 41
Right0 54
a3 41 a4 54
Left0 41 Left1 54
Right0 61
a3 41 a4 54 a5 61
Left0 13 Left1 -842150451 Left2 21
Right0 41 Right1 54 Right2 61
a0 13 a1 -842150451 a2 21 a3 41 a4 54 a5 61
13 -842150451 21 41 54 61

错误代码:Right[n2 + 1]=INF; 修改为 Right[n2]=INF;
baoxiaofei123 2010-05-07
  • 打赏
  • 举报
回复
小弟在此谢过各位的解释。。。
CCPP_Rookie 2010-05-07
  • 打赏
  • 举报
回复
竟然把空格都弄没了

可以在纸上试着模拟一下程序调用过程,不用实际的单步调试。
比如
设left = 0, right = 4;
merge(a, 0, 4);
merge(a, 0, 2);---
merge(a, 0, 1);---
merge(a, 0, 0);---(不满足条件,返回)
merge(a, 1, 2);---
merge(a, 2, 2);---(不满足条件,返回)
merge();(对0-2区间排序)
merge(a, 2, 4); ---
………………
(下略)
CCPP_Rookie 2010-05-07
  • 打赏
  • 举报
回复
可以在纸上试着模拟一下程序调用过程,不用实际的单步调试。
比如
设left = 0, right = 4;
merge(a, 0, 4);
merge(a, 0, 2);---
merge(a, 0, 1);---
merge(a, 0, 0);---(不满足条件,返回)
merge(a, 1, 2);---
merge(a, 2, 2);---(不满足条件,返回)
merge();(对0-2区间排序)
merge(a, 2, 4); ---

………………
(下略)
baoxiaofei123 2010-05-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 rider628 的回复:]
我测试了,下面的代码功能正常
#include <stdio.h>

#define INF 2147483647 //定义int类型的无穷大!

void merge(int *a,int p,int q,int r) //a为数组的首指针
{
int n1=q-p+1,n2=r-q; //p<=q<r 为下标
int*Left=new int[n1+1],*Right=new ……
[/Quote]

还是刚哥猛!谢了!
Rider628 2010-05-07
  • 打赏
  • 举报
回复
我测试了,下面的代码功能正常
#include <stdio.h>

#define INF 2147483647 //定义int类型的无穷大!

void merge(int *a,int p,int q,int r) //a为数组的首指针
{
int n1=q-p+1,n2=r-q; //p<=q<r 为下标
int*Left=new int[n1+1],*Right=new int[n2+1];

for(int i(0);i<n1;++i)
{
Left[i]=a[p+i];
std::cout << "Left" << i << " " << Left[i] << " ";
}
std::cout << std::endl;

for(int i(0);i<n2;++i)
{
Right[i]=a[q+i+1];
std::cout << "Right" << i << " " << Right[i] << " ";
}
std::cout << std::endl;

Left[n1]=INF;
Right[n2]=INF;
int i=0;int j=0;

for(int k(p);k<=r;++k)
{
if(Left[i]<=Right[j])
{
a[k]=Left[i];
std::cout << "a" << k << " " << a[k] << " ";
i++;
}
else
{
a[k]=Right[j];
std::cout << "a" << k << " " << a[k];
++j;
}
}
std::cout << std::endl;
}

void merge_sort(int*a, int p,int r)
{
int q;
q=(p+r)/2;
if (p<r)
{

merge_sort(a,p,q);
merge_sort(a,q+1,r);
merge(a,p,q,r);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
int a[6] = {21,63,13,41,54,61};
for (int i = 0; i < 6; i++ )
{
std::cout << " " << a[i];
}
std::cout << std::endl;

merge_sort(a, 0, 5);

for (int i = 0; i < 6; i++ )
{
std::cout << " " << a[i];
}
std::cout << std::endl;

system("pause");

return 0;
}


下面是测试的时候输出的:


21 63 13 41 54 61
Left0 21
Right0 63
a0 21 a1 63
Left0 21 Left1 63
Right0 13
a0 13a1 21 a2 63
Left0 41
Right0 54
a3 41 a4 54
Left0 41 Left1 54
Right0 61
a3 41 a4 54 a5 61
Left0 13 Left1 21 Left2 63
Right0 41 Right1 54 Right2 61
a0 13 a1 21 a2 41a3 54a4 61a5 63
13 21 41 54 61 63

错误的输出日志:(仔细观察发现程序中的错误)
21 63 13 41 54 61
Left0 21
Right0 63
a0 21 a1 63
Left0 21 Left1 63
Right0 13
a0 13a1 -842150451a2 21
Left0 41
Right0 54
a3 41 a4 54
Left0 41 Left1 54
Right0 61
a3 41 a4 54 a5 61
Left0 13 Left1 -842150451 Left2 21
Right0 41 Right1 54 Right2 61
a0 13 a1 -842150451 a2 21 a3 41a4 54a5 61
13 -842150451 21 41 54 61
CCPP_Rookie 2010-05-07
  • 打赏
  • 举报
回复
[Quote=引用楼主 baoxiaofei123 的回复:]
在网上见到一个归并排序的code:
void merge_sort(int *a,int left,int right)
{
int half;
if(left<right)
{
half=(int)((left+right)/2);
merge_sort(a,left,half);/*这两条语句的执行过程是怎么样的?*/ ---对左子表进行归并排序

merge_sort(a,half+1,right); -----再来一轮,对右子表进行归并排序
merge(.....);/*具体排序函数*/
}
}
[/Quote]
要理解递归的过程。

别忘了还有个条件if(left<right),当递归的某一层right<=left是,这个函数就能一层层的弹栈、返回了

Rider628 2010-05-07
  • 打赏
  • 举报
回复
void merge(.....)
{
...../*具体就是对分割好的子数组排序,很简单。不写了*/
}
把这个发出来
Rider628 2010-05-07
  • 打赏
  • 举报
回复
从逻辑上分析,没有发现问题,把这个发出来 我跑一边,调调看是什么问题
bobo364 2010-05-07
  • 打赏
  • 举报
回复
貌似这两句一个说的是值可能在左边,另一句说是值可能在右边,应该有个if else才对
baoxiaofei123 2010-05-07
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhao4zhong1 的回复:]
“给出一个尽量少的简单数据,单步跟踪一遍整个过程。”
个人认为这才是弄懂递归程序具体是如何工作的不二法门。
[/Quote]
谢谢 只是明天要去考试。。。很久没看C了 以前的都忘得差不多了。。。
赵4老师 2010-05-07
  • 打赏
  • 举报
回复
“给出一个尽量少的简单数据,单步跟踪一遍整个过程。”
个人认为这才是弄懂递归程序具体是如何工作的不二法门。

69,379

社区成员

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

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