【问题描述】将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来的两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。
【输入形式】三行,第一行:两个有序链表中元素的个数,第二行:第一个链表中的元素以空格间隔,第三行:第二个链表中的元素以空格间隔
【输出形式】合并后的没有重复元素的有序链表中的数据以空格间隔
【样例输入】
3 4
1 5 7
2 4 7 9
【样例输出】1 2 4 5 7 9
【样例说明】
【评分标准】
#include <bits/stdc++.h>
using namespace std;
// 定义有序链表节点结构
struct OLNode
{
int data;
OLNode *next;
};
// 定义有序链表类型
typedef OLNode *OLinkList;
// 在有序链表中查找插入位置的前驱节点
OLNode *getPre(OLinkList h, int e)
{
OLNode *pre = h;
while (pre->next && pre->next->data < e)
pre = pre->next;
return pre;
}
// 创建有序链表
void createOLinkList(OLinkList &h, int n)
{
h = new OLNode;
h->next = NULL;
OLNode *pre, *p;
int e;
for (int i = 1; i <= n; i++)
{
cin >> e;
p = new OLNode;
p->data = e;
pre = getPre(h, e); // 获取插入位置的前驱节点
p->next = pre->next;
pre->next = p; // 将新节点插入到前驱节点之后
}
}
// 打印有序链表
void printOLinkList(OLinkList h)
{
OLNode *p;
p = h->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
// 合并两个有序链表
void olistUnion(OLinkList ha, OLinkList hb)
{
OLinkList h = ha;
OLinkList p = ha->next;
OLinkList q = hb->next;
while (p && q)
{
if (p->data < q->data)
{
h = p;
p = p->next;
h->next = q;
}
else if (p->data > q->data)
{
h = q;
q = q->next;
h->next = p;
}
else
{
h->next = p;
h = p;
p = p->next;
OLinkList tmp = q->next;
delete (q);
q = tmp;
}
}
h->next = p ? p : q;
delete (hb);
}
int main()
{
int m, n;
OLinkList ha, hb;
cin >> m >> n;
createOLinkList(ha, m); // 创建第一个有序链表
createOLinkList(hb, n); // 创建第二个有序链表
olistUnion(ha, hb); // 合并两个有序链表
printOLinkList(ha); // 打印合并后的链表
return 0;
}
getPre
函数用于在有序链表中找到插入位置的前驱节点,而olistUnion
函数用于将两个有序链表合并为一个有序链表。
首先,createOLinkList
函数用于创建有序链表。它通过调用getPre
函数找到要插入新节点的位置的前驱节点,然后将新节点插入到前驱节点之后,以保持链表的有序性。
然后,olistUnion
函数用于合并两个有序链表。它遍历两个链表,并根据节点值的大小关系,将节点连接到合并链表的尾部。如果两个节点的值相等,则删除其中一个节点。
最后,printOLinkList
函数用于打印链表中的元素。