用顺序表A和B表示的两个线性表,元素的个数分别是m和n, 若表中数据都是从小到大顺序排列的,且这(m+n)个数据中没有重复的。
(1) 设计一个算法将此两个线性表合并成一个,仍是数据由小到大排列的线性表,存储到另一个顺序表C中。
(2) 如果顺序表B的大小为(m+n)个单元,是否可不利用顺序表C而将合成的线性表存放于顺序表B中? 试设计算法。
(3) 设顺序表A有m+n个元素,且前m个元素,后n个元素有序,设计一个算法,使得整个顺序表有序。
解答:
1)用
i
i
i和
j
j
j分别扫描顺序表
A
A
A和
B
B
B, 比较它们的当前元素,将较小者复制到顺序表
C
C
C中,这一过程循环到其中一个顺序表扫描完毕为止。将另一个顺序表余下的元素全部复制到顺序表C中。算法如下:
void meger1(SqList *&A, SqList *&B, SqList *&C){
int i=0,j=0,k=0; //i扫描A,j扫描B
while(i< A->length && j< B->length)
{
if (A->data[i] < B->data[j])
{
C->data[k] = A->data[i];
i++; k++;
}
else
{
C->data[k] = B->data[j];
j++; k++;
}
}
while(i< A->length){ //若A未扫描完,则将A剩余的元素加到C中
C->data[k] =A->data[i];
i++; k++;
}
while(j< B->length){ //若B未扫描完,则将B剩余的元素加到C中
C->data[k] = B->data[j];
j++; k++;
}
C->length=k;
}
本算法的时间复杂度为
O
(
m
+
n
)
O(m+n)
O(m+n), 空间复杂度为
O
(
1
)
O(1)
O(1)。
2) 可以,将顺序表A中较小元素插入到B中即可,算法如下:
void meger2(SqList *&A, SqList *&B){
int i=0,j=0,k;
while(i< A->length){
if (A->data[i] > B->data[B->length-1]) //若A->data[i]大于B中所有元素
{
B->data[B->length]=A->data[i]; //将A->data[i]插入到B末尾
B->length++; i++;
}
else if(A->data[i] < B->data[j]){
for(k=B->length-1; k>=j; k--)
B->data[k+1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移
B->data[j]=A->data[i]; //在位置j处插入
B->length++; //顺序表长度加1
i++; j++;
}
else j++;
}
}
本算法的时间复杂度
O
(
m
∗
n
)
O(m*n)
O(m∗n), 空间复杂度为
O
(
1
)
O(1)
O(1)。
3) 将顺序表A的后半部分插入到前半部分中,使整个表有序。算法如下:
void merge3(SqList *&A,int m,int n){
int i=0,j=m,k; //j扫描后半部分的有序表,并记录有序表前半部分的长度
ElemType tmp;
while(j< A->length && i<j){
if(A->data[j] > A->data[j-1]) //整个表有序,退出循环
break;
else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中
{
tmp=A->data[j];
for(k=j-1; k>=i; k--) //将A->data[i]及之后的元素后移
A->data[k+1] = A->data[k];
A->data[i]=tmp; //将A->data[j]插入到i处
i++; j++;
}
else i++;
}
}
本算法的时间复杂度为
O
(
m
∗
n
)
O(m*n)
O(m∗n), 空间复杂度为
O
(
1
)
O(1)
O(1)。
完整代码如下:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#define MaxSize 50
typedef int ElemType;
typedef struct {
ElemType data[MaxSize];
int length;
}SqList;
void DispList(SqList *L) { //输出L中所有的元素
int i;
if (L->length == 0) return;
for (i = 0; i < L->length; i++)
printf("%d ", L->data[i]);
printf("\n");
}
void meger1(SqList *&A, SqList *&B, SqList *&C) {
int i = 0, j = 0, k = 0; //i扫描A,j扫描B
while (i < A->length && j < B->length)
{
if (A->data[i] < B->data[j])
{
C->data[k] = A->data[i];
i++; k++;
}
else
{
C->data[k] = B->data[j];
j++; k++;
}
}
while (i < A->length) { //若A未扫描完,则将A剩余的元素加到C中
C->data[k] = A->data[i];
i++; k++;
}
while (j < B->length) { //若B未扫描完,则将B剩余的元素加到C中
C->data[k] = B->data[j];
j++; k++;
}
C->length = k;
}
void meger2(SqList *&A, SqList *&B) {
int i = 0, j = 0, k;
while (i < A->length) {
if (A->data[i] > B->data[B->length - 1]) //若A->data[i]大于B中所有元素
{
B->data[B->length] = A->data[i]; //将A->data[i]插入到B末尾
B->length++; i++;
}
else if (A->data[i] < B->data[j]) {
for (k = B->length - 1; k >= j; k--)
B->data[k + 1] = B->data[k]; //将元素B->data[j]及之后的元素依次后移
B->data[j] = A->data[i]; //在位置j处插入
B->length++; //顺序表长度加1
i++; j++;
}
else j++;
}
}
void merge3(SqList *&A, int m, int n) {
int i = 0, j = m, k; //j扫描后半部分的有序表,并记录有序表前半部分的长度
ElemType tmp;
while (j < A->length && i < j) {
if (A->data[j] > A->data[j - 1]) //整个表有序,退出循环
break;
else if (A->data[j] < A->data[i]) //将A->data[i]插入到前半部分中
{
tmp = A->data[j];
for (k = j - 1; k >= i; k--) //将A->data[i]及之后的元素后移
A->data[k + 1] = A->data[k];
A->data[i] = tmp; //将A->data[j]插入到i处
i++; j++;
}
else i++;
}
}
int main()
{
SqList *A = (SqList*)malloc(sizeof(SqList));
A->length = 0;
A->data[0] = 3;
A->data[1] = 7;
A->data[2] = 15;
A->data[3] = 18;
A->data[4] = 26;
A->length = 5;
SqList *B = (SqList*)malloc(sizeof(SqList));
B->length = 0;
B->data[0] = 4;
B->data[1] = 11;
B->data[2] = 20;
B->length = 3;
SqList *C = (SqList*)malloc(sizeof(SqList));
C->length = 0;
SqList *A2 = (SqList*)malloc(sizeof(SqList));
A2->length = 0;
A2->data[0] = 3;
A2->data[1] = 7;
A2->data[2] = 11;
A2->data[3] = 20;
A2->data[4] = 4;
A2->data[5] = 8;
A2->data[6] = 16;
A2->length = 7;
DispList(A);
DispList(B);
//1)第一种方法合并
//meger1(A,B,C);
//DispList(C);
//2) 第二种方法合并
meger2(A, B);
DispList(B);
//3) 对A2进行排序
//DispList(A2);
//merge3(A2,4,3);
//DispList(A2);
free(A);
free(B);
free(C);
free(A2);
system("pause");
return 0;
}
效果如下: