题目要求
将两个非递减的有序链表合并成一个非递增的有序链表。要求链表仍使用原来两个链表的存储空间,不另外使用其他的存储空间,表中运行有重复的元素。
题解
与合并有序链表1类似的思路,通过更改结点的指针域来重新建立元素之间的线性关系,得到新链表。
有两个关键点:
- 合并的链表与原链表顺序相反,利用前插法建立链表,形成递减序列。
- 当一个表到达表尾为空时,另一个非空表的剩余元素应该利用前插法依次插入Lc的头结点之后,而不能全部链接在Lc表的最后。
/*
将两个非递减的有序链表合并成一个非递增的有序链表。要求链表仍使用原来两个链表的存储空间,不另外使用其他的存储空间,表中运行有重复的元素。
*/
#include <iostream>
using namespace std;
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList;
/*
创建链表
*/
void createList(LinkList &L) {
// 初始化头结点
L = new LNode;
L->next = NULL;
int n;
LinkList p, q = L;
cout << "创建链表元素的个数:";
cin >> n;
cout << "输入链表的元素:";
// 后插法创建链表
for (int i = 0; i < n; ++i) {
p = new LNode;
cin >> p->data;
p->next = NULL;
q->next = p;
q = p;
}
cout << "创建链表成功!" << endl;
}
/*
打印链表中的元素
*/
void printList(LinkList L) {
LinkList p = L->next; // 首元结点
while (p != NULL) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
/*
合并链表
*/
void mergeList(LinkList &La, LinkList &Lb, LinkList &Lc) {
LinkList pa = La->next; // La的首元结点
LinkList pb = Lb->next; // Lb的首元结点
LinkList q;
Lc = La; // Lc的头结点为La的头结点
Lc->next = NULL; // 头插法
while (pa || pb) {
if (!pa) {
q = pb; // q为待插入结点
pb = pb->next;
} else if (!pb) {
q = pa;
pa = pa->next;
} else if (pa->data <= pb->data) {
q = pa;
pa = pa->next;
} else {
q = pb;
pb = pb->next;
}
// q指向的结点插在Lc的后面
q->next = Lc->next;
Lc->next = q;
}
}
int main() {
LinkList La = NULL, Lb = NULL, Lc = NULL;
cout << "-创建链表La-" << endl;
createList(La);
cout << "-创建链表Lb-" << endl;
createList(Lb);
cout << "链表La的元素:" << endl;
printList(La);
cout << "链表Lb的元素:" << endl;
printList(Lb);
mergeList(La, Lb, Lc);
cout << "合并后的链表Lc的元素:" << endl;
printList(Lc);
return 0;
}