我有文字“DIRESTRAITS”,在我的任务中,我喜欢做递归的Mergesort。在任务中我提到了这段代码:
void mergesort (itemType a[], int l, int r)
{
int i,j,k,m;
if (r>l)
{
m = (r+l)/2;
mergesort(a,l,m);
mergesort(a,m+l,r);
for (i = m+1; i > l; i--) b[i--] = a[i-1]
for (j = m; j < r; j++) b[r+m-j] = a[j+1];
for (k = 1; k <= r; k++)
a[k] = (b[i]<=b[j]& i<= m) ? b[i++] : b[j--];
}
}
这就是我在任务文本中得到的代码。该任务告诉我每次完成第3个for循环时绘制,并标记已经涉及的键。这是答案(我需要帮助才能理解上面的代码):
Start:
D I R E S T R A I T S
D I
D I R
E S
E S T
D E I R S T
A R
A I R
S T
A I R S T
Finish: A D E I I R R S S T T
答案 0 :(得分:1)
示例代码有问题,例如第二次递归调用mergesort的第二个参数应该是m + 1,而不是m + L.我不确定示例代码中还有什么其他内容。
自顶向下合并排序以递归方式将数组拆分为子数组,直到子数组大小为1(或为零)。在通过递归分裂数组产生大小为1的子对数之前,不执行数据的合并(排序)。然后,由于可以将大小为1的数组视为已排序,因此合并左侧和右侧子阵列以创建大小为2的已排序子阵列,然后将这些已排序的子阵列合并以形成更大的已排序子阵列。此过程遵循递归调用链向下(拆分)和向上(合并),直到整个数组被排序(深度优先,左边第一个)。
一个工作示例:
#include <stdio.h>
/* 012345678901234 */
static char a[16] = "DIRESTRAITS ";
static char b[16] = " ";
void mergesort (char a[], int l, int r)
{
int i,j,k,m;
if (r>l)
{
m = (r+l)/2;
mergesort(a,l,m);
mergesort(a,m+1,r);
for (i = l; i <= r; i++)b[i] = a[i];
i = l;
j = m+1;
for (k = l; k <= r; k++)
a[k] = (j > r || i <= m && b[i] <= b[j]) ? b[i++] : b[j++];
for (k = 0; k < l; k++)
printf(" ");
for (k = l; k <= r; k++)
printf("%c ", a[k]);
printf("\n");
}
}
int main()
{
int k;
for(k = 0; k <= 10; k++)
printf("%c ", a[k]);
printf("\n");
mergesort(a, 0, 10);
return 0;
}
答案 1 :(得分:0)
Mergesort,顾名思义,基于合并:将两个排序列表合并为一个。该算法将要分类的列表分为两个(粗略地),并对每一半进行排序(这是通过递归调用merge sort
来完成的)。接下来的两个循环各自将数组a
的一半结果复制到数组b
;最后一个循环从a
重新填充b
,沿着b
的两半走,并且在每一步中,取两个中较小的一个(或者,一半使用了一半)向上,只是把它从另一个中取出),以便下一个值进入a
。