wenpinglaoyao1 于 2015.07.14 14:56 提问

`````` #include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define  MAX 100
int b;
int arr[MAX],tearr[MAX];

void merge(int a[],int t[],int lhead, int rtail)
{
int lt, k, mid, rt;
rt = mid+1;
{
goto tailsort;
}

merge(a,t, mid+1,rtail);

while (lt<=mid && rt<=rtail)
{
t[k++] = (a[lt]<=a[rt])?a[lt++]:a[rt++];
}

while (lt<=mid)
{
t[k++] = a[lt++];
}
while (rt<=rtail)
{
t[k++] = a[rt++];
}

for (b=0; b<MAX;b++)
{
a[b] = t[b];
}

tailsort:    ;
}

void main()
{

for (i=0; i<MAX;i++)
{
arr[i] = rand();
}

for(i=0; i<MAX; i++) printf("%d  ",arr[i]);
system("pause");

head = 0; tail = MAX;

for (i=0; i<MAX;i++)
{
arr[i] = tearr[i];
}

for (i=0; i<MAX;i++)
{
printf(" %d",arr[i]);
}
system("pause");
}
``````

4个回答

wenpinglaoyao   2015.07.14 17:11

#include
#include
#include
#define MAX 100
int b;
int arr[MAX],tearr[MAX];

void merge(int a[],int t[],int lhead, int rtail)
{
int lt, k, mid, rt;
rt = mid+1;
{
goto tailsort;
}

``````merge(a,t, lhead,mid);
merge(a,t, mid+1,rtail);

while (lt<=mid && rt<=rtail)
{
t[k++] = (a[lt]<=a[rt])?a[lt++]:a[rt++];
}

while (lt<=mid)
{
t[k++] = a[lt++];
}
while (rt<=rtail)
{
t[k++] = a[rt++];
}

for (b=0; b<MAX;b++)
{
a[b] = t[b];
}
``````

tailsort: ;
}

void main()
{
int i;

``````for (i=0; i<MAX;i++)
{
arr[i] = rand();
}

for(i=0; i<MAX; i++) printf("%d  ",arr[i]);
system("pause");

/*****问题出在这里******/
for (i=0; i<MAX;i++)
{
tearr[i] = arr[i];
}
/*****加上这个循环即可，至于为什么，楼主请自行考虑！******/

merge(arr,tearr, 0, MAX-1);

for (i=0; i<MAX;i++)
{
printf(" %d",arr[i]);
}
system("pause");
``````

}

wenpinglaoyao1 哈哈！我明白了！真是一个for循环惊醒梦中人啊！找到问题所在了！！真的非常感谢！！！

wenpinglaoyao1 谢谢，真是辛苦了！大概看了一下您的代码，改动的更少，稍等下，我去测验

caozhy      2015.07.14 16:27
wenpinglaoyao1 晕死，如果我只是为了排序而写代码，那不如直接抄网上的了。之所以写这个代码，纯粹是锻炼一下对递归调用自身函数的掌握。这个代码昨天就写好了，最后只剩下这个问题，但两天了我都没找到bug所在，所以才搬出来求助大牛的

u010089908   2015.07.14 16:18
`````` #include<iostream>
#include<cstdlib>
#include<cstdio>
#include<ctime>
#define MAX 10
using namespace std;
int b;
int arr[2][MAX];

void merge(int a[],int t[],int lhead, int rtail, int ifor)
{
int lt, rt , k, mid, rduan;
//    {
//        goto tailsort;
//    }
//    merge(a,t, mid+1,rtail);
for (int i=lhead; i+ifor <= rtail; i += ifor*2 )
{
lt = i;
rt = i + ifor;
mid = rt - 1;
rduan = rt+ifor-1;
if (rduan > rtail) rduan = rtail;
while (lt<=mid && rt<=rduan)
{
t[k++] = (a[lt]<=a[rt])?a[lt++]:a[rt++];
}
while (lt<=mid)
{
t[k++] = a[lt++];
}
while (rt<=rduan)
{
t[k++] = a[rt++];
}
}

//    for (b=0; b<MAX;b++)
//    {
//        a[b] = t[b];
//    }
//    tailsort: ;
}

int main()
{
srand((unsigned)time(NULL));//用时间来做随机种子,使得每次运行得到的数列不同
for (i=0; i<MAX;i++)
{
arr[0][i] = rand()%(50-10+1)+10; //可以改用rand()%(Y-X+1)+X，表示在[X,Y]中随机一个数
}

for(i=0; i<MAX; i++) printf("%d ",arr[0][i]);
system("pause");

head = 0; tail = MAX - 1;
int next = 1;
int ifor = 1;
while (ifor < MAX - 1)
{
next = 1 - next;
ifor *= 2;
}

//    for (i=0; i<MAX;i++)
//    {
//        arr[i] = tearr[i];
//    }

for (i=0; i<MAX;i++)
{
printf(" %d",arr[1-next][i]);
}
system("pause");
return 0;
}

``````
u010089908 回复黑色梧桐叶: 递归调用自然可以，不过时间会慢些，有的递归还会造成栈溢出。至于你写的merge函数，更新赋值这一块浪费了太多操作，所以改成了next标记法。

wenpinglaoyao1 谢谢！为什么主循环里面有个for循环调用函数，难道递归调用自身不方便吗？

u010089908 楼主原先的合并排序算法有逻辑性错误，楼主可以看下我上面贴的代码，在你的基础上改的，能直接运行。

se7en_q   2015.07.14 16:09

1、while (lt<=mid && rt<=rtail)
{
t[k++] = (a[lt]<=a[rt])?a[lt++]:a[rt++];
}

2、 while (lt<=mid)
{
t[k++] = a[lt++];
}
3、 while (rt<=rtail)
{
t[k++] = a[rt++];
}

wenpinglaoyao1 不对，我早就注意这个了，还做了好多图，问题不出在这里