本程序实现了一个将五位链表合并,可以通过更改参数修改链表长度。
实现方法主要是尾插法进行合并链表的修改。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct LinkList { /*创建单向链表*/
int data; /*数据域*/
struct LinkList* next; /*指针域*/
};
int main() {
struct LinkList *Head1 = new LinkList;/*给第一个链表的头节点分配内存*/
Head1->next = NULL; /*头节点指空*/
struct LinkList* p;/*创建一个节点*/
p = Head1;/*将这个节点指向头节点*/
cout<<"请按照由大到小顺序输入第一个5位链表"<<endl;/*创建链表*/
for (int i = 0; i < 5; i++) {
struct LinkList* q = new LinkList;/*生成新结点*/
cin>> q->data;/*输入元素赋值给新结点的数据域*/
p->next = q;/*将新节点q插入尾结点p之后*/
q->next = NULL;
p = q;/*把p变成新的尾结点,q结点起到一个过渡作用*/
}
p = Head1->next;/*指向next是为了方便下面和r链表的数据比较,如果不next则p指向NULL比较出错,且编译器不允许p->next->data之间的数据比较*/
struct LinkList* Head2 = new LinkList;/*重复上述操作,创建新链表r*/
Head2->next = NULL;
struct LinkList* r;
r = Head2;
cout<<"请按照由大到小顺序输入第二个5位链表"<<endl;
for (int k = 0; k < 5; k++) {
struct LinkList* s = new LinkList;
cin>>s->data;
r->next = s;
s->next = NULL;
r = s;
}
if (!p && !r) { /*判断链表是否都已经创建好*/
cout<<"error";
return 0;
}
r = Head2->next;
struct LinkList* Head3 = new LinkList;/*创建合并链表*/
Head3->next = NULL;
struct LinkList* e;
e = Head3;
struct LinkList* temp;/*创建一个中间指针方便链表的删除*/
while (p && r) {/*开始链表的合并,为了保持合并后还是递增的、无重复的列表,需要判断链表数据大小*/
if (p->data < r->data) {
e->next = p;/*如果p1号结点小,将其合并到e,e从头指针开始,头结点下一位指向p*/
e = p;/*此时p是链表新的尾结点,再让e=p,e指向新的尾结点p,合并成功(尾插法合并)*/
p = p->next;/*p向下指,进行下一次判断*/
}
else if (p->data > r->data) {/*执行过程同上*/
e->next = r;
e= r;
r = r->next;
}
else if (p->data == r->data) {/*如果两结点数据相同,需要删除一个数据*/
e->next = p;
e = p;
p = p->next;/*先合并一个数据*/
temp = r->next;/*将另一个数据删除,找一个中间结点,指向r下一位*/
delete r;/*释放r*/
r = temp;/*r指回r的下一位*/
}
}
/*!!!在运行时发现一个链表全部合并了,另一个链表剩下的元素总不出现在合并后的链表中,
发现while(){}再有一个链表合并完之后就停止合并了,导致另一个链表数据丢失,
下列函数判断到底是哪个链表没合并完全,然后把合并工作完成*/
if (p != NULL) {
e->next = p;
}
else if (r != NULL) {
e->next = r;
}
e = Head3;/*输出新合并的链表,检验合并结果*/
while (e->next!= NULL) {
cout<< e->next->data<<'\t';
e = e->next;
}
return 0;
}