在中国大学MOOC上学习了分别用单链表和顺序表实现有序表的二路归并,为加深印象与理解,自己操作了一下。
有序表中所有有序表以递增或递减的方式有序排列。
两个有序表L1和L2合并成一个有序表L3。
用单链表实现
#include<stdio.h>//有序表的二路归并单链表实现
#include<stdlib.h>
typedef struct node
{
int data;//存放元素
struct node *next;//指向后继节点的指针
}list;
void Createlist(list *&L,int n)//尾插法建立单链表
{
list *s, *r;
int i;
L = (list*)malloc(sizeof(list));//设置一个头节点
r = L;//r始终指向尾节点
printf("输入有序表的元素:\n");
for (i = 0; i < n; i++)
{
s= (list*)malloc(sizeof(list));
scanf_s("%d", &s->data);
r->next = s;
r = s;
}
r->next = NULL;//最后的尾节点要指向NULL
}
void combine(list *L1, list *L2, list *&L3)//有序表L1和L2二路归并为有序表L3
{
list *p =L1->next, *q =L2->next,*r,*s;//p扫描L1,q扫描L2
L3= (list*)malloc(sizeof(list));//L3为头节点,也用尾插法建立有序表L3
r = L3;
while (p != NULL && q != NULL)
{
if (p->data < q->data)
{
s= (list*)malloc(sizeof(list));
s->data = p->data;
r->next = s;
r = s;
p = p->next;
}
else
{
s= (list*)malloc(sizeof(list));
s->data = q->data;
r->next = s;
r = s;
q = q->next;
}
}
while (p != NULL)
{
s= (list*)malloc(sizeof(list));
s->data = p->data;
r->next = s;
r = s;
p = p->next;
}
while (q != NULL)
{
s = (list*)malloc(sizeof(list));
s->data = q->data;
r->next = s;
r = s;
q = q->next;
}
r->next = NULL;
}
void print(list *L3)//打印链表
{
list *p=L3->next;
while (p != NULL)
{
printf("%d ", p->data);
p = p->next;
}
}
int main()
{
list *L1, *L2, *L3;
int n1, n2;
printf("输入第一个有序表的长度:\n");
scanf_s("%d", &n1);
Createlist(L1, n1);//创建链表
printf("输入第二个有序表的长度:\n");
scanf_s("%d", &n2);
Createlist(L2, n2);
combine(L1, L2, L3);//合并
printf("合并后的有序表为:\n");
print(L3);//打印合并后的链表
system("pause");
}
运行结果如下:
L1和L2中每个元素恰好遍历一遍,时间复杂度和空间复杂度都为(m+n)。
用顺序表实现
#include<stdio.h>//用顺序表实现二路合并
#include<stdlib.h>
#define MaxSize 100
typedef struct//定义顺序表
{
int data[MaxSize];
int length;
}list;
void Create(list *&L, int n)//创建顺序表
{
int i;
L = (list*)malloc(sizeof(list));
printf("输入该有序表中的元素:\n");
for (i = 0; i < n; i++)
{
scanf_s("%d", &L->data[i]);
}
L->length = n;
}
void combine(list *L1, list *L2, list *&L3)//合并顺序表
{
int i,j,k;
i = j = k= 0;
L3 = (list*)malloc(sizeof(list));
while (i < L1->length&&j < L2->length)
{
if (L1->data[i] < L2->data[j])
{
L3->data[k] = L1->data[i];
i++;
k++;
}
else
{
L3->data[k] = L2->data[j];
j++;
k++;
}
}
while (i != L1->length)
{
L3->data[k] = L1->data[i];
i++;
k++;
}
while (j != L2->length)
{
L3->data[k] = L2->data[j];
j++;
k++;
}
L3->length = k;
}
void print(list *L3)//打印链表
{
int i;
printf("合并后的有序表为:\n");
for (i = 0; i < L3->length; i++)
{
printf("%d ", L3->data[i]);
}
}
int main()
{
list *L1, *L2, *L3;
int n1, n2;
printf("输入第一个有序表的长度:\n");
scanf_s("%d", &n1);
Create(L1, n1);
printf("输入第二个有序表的长度:\n");
scanf_s("%d", &n2);
Create(L2, n2);
combine(L1, L2, L3);
print(L3);
system("pause");
}
L1和L2中每个元素恰好遍历一遍,时间复杂度和空间复杂度都为(m+n)。
如果还有更好的方法,请指出。