顺序表应用5:有序顺序表归并
Description
已知顺序表A与B是两个有序的顺序表,其中存放的数据元素皆为普通整型,将A与B表归并为C表,要求C表包含了A、B表里所有元素,并且C表仍然保持有序。
Input
输入分为三行:
第一行输入m、n(1<=m,n<=10000)的值,即为表A、B的元素个数;
第二行输入m个有序的整数,即为表A的每一个元素;
第三行输入n个有序的整数,即为表B的每一个元素;
Output
输出为一行,即将表A、B合并为表C后,依次输出表C所存放的元素。
Sample
Input
5 3
1 3 5 6 9
2 4 10
Output
1 2 3 4 5 6 9 10
第一种做法
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[10010], b[10010], c[20020];//先定义三个数组,a、b用于存储输入,c用于归并且数组c的大小为数组a和b的大小之和
int i, m, n, j, k, l;
scanf("%d %d", &m, &n);
for (i = 0; i < m; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i++)
{
scanf("%d", &b[i]);
}
j = k = 0;
for (l = 0; l < m + n;)//数据小的优先存入
{
if (j == m && k < n)//①,当第一个数组处理完毕且第二个数组还有剩余元素
{
c[l] = b[k];
l++;
k++;
}
else if (j < m && k == n)//②当第二个数组处理完毕且第一个数组还有剩余元素
{
c[l] = a[j];
l++;
j++;
}
else if (a[j] <= b[k])//③,两个数组都未处理完毕,下同
{
c[l] = a[j];
l++;
j++;
}
else if (a[j] > b[k])//④
{
c[l] = b[k];
l++;
k++;
}
/*四个判断语句中③和④要放在①和②后面,先判断是否已经有一个数组已被处理完毕,若是,则将剩下的那个数组的剩下的元素按顺序存入c中,
如果③和④不在最后面,且已经应有一个数组被处理完毕,那么系统会按照判断语句的先后给已经处理完毕的数组再多给一个垃圾数据,影响
另一个数组的处理*/
}
for (i = 0; i < l -1; i++)
{
printf("%d ", c[i]);
}
printf("%d", c[l - 1]);
}
在if-else if分支结构中,如果前面有一个条件成立,则下面的分支结构将不会被执行;而if-if分支结构则不然——只要条件成立就会执行。
另一种做法
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i, j, n, m, a[10010], b[10010], c[20020], t, sum;//这里要注意合并后的数组的大小为之前的两个数组的大小的和
scanf("%d %d", &m, &n);
sum = m + n;
for (i = 0; i < m; i++)
{
scanf("%d", &a[i]);
}
for (i = 0; i < n; i++)
{
scanf("%d", &b[i]);
}
i = j = 0;
for (t = 0; t < sum; t++)
{
if (i < m && j < n)//两个数组都没有被完全并入新的数组
{
if (a[i] <= b[j])
{
c[t] = a[i];
i++;
}
else
{
c[t] = b[j];
j++;
}
}
else if (i == m && j < n)//数组a被“掏空”
{
c[t] = b[j];
j++;
}
else if (i < m && j == n)//数组b被“掏空”
{
c[t] = a[i];
i++;
}
}
for (i = 0; i < t - 1; i++)
{
printf("%d ", c[i]);
}
printf("%d", c[t - 1]);
}
这种做法相对于第一种做法不必在乎if-else的语句的位置顺序,因为在两个数组都没有被“掏空”的情况下作了判断