问题引入:
今天在写牛客网的题时碰到一道关于数组合并排序的问题,这道题的怪异点在于给定的数组是升序排列。
对于此,我有以下代码:
//总体思路是运用指针逐步比较,在比较的过程中还打印出来,
//不用新数组存储,这样可以节省一点运行时间,但结果还是寄了···
#include <stdio.h>
int main() {
int n, m;
int i = 0;
int j = 0;
int flag = 1;
scanf("%d %d", &n, &m);
int arr01[1000] = { 0 };
int arr02[1000] = { 0 };
for (i = 0; i < n; i++)
{
scanf("%d", &arr01[i]);
}
arr01[i] = -1;
for (j = 0; j < m; j++)
{
scanf("%d", &arr02[j]);
}
arr02[j] = -1;
//int* p = new_arr(arr01, arr02, sizeof(arr01) / sizeof(int), sizeof(arr02) / sizeof(int));
i = 0;
j = 0;
//k = 0;
int arr[2002] = { 0 };
while (flag)
{
if (*(arr01 + i) < *(arr02 + j) && *(arr01 + i) > 0)
{
//arr[k++] = *(arr01 + i);
printf("%d ", *(arr01 + i));
i++;
}
else if (*(arr01 + i) > *(arr02 + j) && *(arr02+ j) >0)
{
//arr[k++] = *(arr02 + j);
printf("%d ", *(arr02 + j));
j++;
}
else
{
if (*(arr01 + i) > 0)
{
//arr[k++] = *(arr01 + i);
printf("%d ", *(arr01 + i));
i++;
}
if (*(arr02 + j) > 0)
{
//arr[k++] = *(arr02 + j);
printf("%d ", *(arr02 + j));
j++;
}
}
if (i >= n && j >= m)
{
flag = 0;
}
}
/* for (int z = 0; z < n + m; z++)
{
printf("%d ", arr[z]);
} */
return 0;
}
不知道为什么,0没打出来,并且重复的数也没打出来,运行时间也是超了。万般无奈,只能去网上找找看有什么方法。
救星——归并排序:
归并排序可以很好解决这类问题(将已经排好序的数组合并再进行排序)。
该方法的中心方法就是对两个数组分别使用指针进行追踪,然后就是比大小,接下来看具体实现。
该方法参考自:
这位老兄的博客
实战:
#include <stdio.h>
//编写Merge() 函数来进行归并排序
//只需要从外界传入三个数组的首地址、给定数组的长度即可
void Merge(int* a,int n, int* b ,int m, int* c)
{
int s1 = 0;
int s2 = 0;
int index = 0;
//该while()结束后。此时两个指针必定有一个已经走向了尽头
while(s1 < n && s2 < m)
{
if(*(a + s1) < *(b +s2))
{
c[index++] = a[s1++];
}
else
{
c[index++] = b[s2++];
}
//无需担心有相同数字出现的情况,因为其中一个指针会动,而另一个不会
//在下一个循环会接着比较,如果此while()恰好结束,可以到下两个while()循环中获取
}
//下面的两个循环有一个起作用,负责将剩下的数打印出来
while(s1 < n)
{
c[index++] = a[s1++];
}
while(s2 < m)
{
c[index++] = b[s2++];
}
}
int main()
{
int n, m;
int i = 0;
int j = 0;
int flag = 1;
scanf("%d %d", &n, &m);
int arr01[1000] = { 0 };
int arr02[1000] = { 0 };
int arr[2000] = {0};
for (i = 0; i < n; i++)
{
scanf("%d", &arr01[i]);
}
for (j = 0; j < m; j++)
{
scanf("%d", &arr02[j]);
}
Merge(arr01, n, arr02, m, arr);
for(i = 0; i < n + m; i++)
{
printf("%d ", arr[i]);
}
}
结语:
对于这种问题,使用归并排序可以大大减少运行时间,为我寒假多一点时间玩耍(bushi)。