两个有序链表合并(新表不含重复元素)(记录学习过程)
题目:
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。 要求S3中没有重复元素。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,要求链表中没有重复元素。数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。
输入样例:
在这里给出一组输入。例如:
1 3 3 5 8 -1
2 3 4 6 8 10 -1
输出样例:
在这里给出相应的输出。例如:
1 2 3 4 5 6 8 10
第一个方法(很麻烦)
因为输入的l1,l2两个链表可能有重复项,我一开始的思路是先分别把l1 和l2 两个链表都进行了对重复项处理,即通过一个循环来遍历,遇到重复项则把当前的指针指向的节点的next指针指向下下个节点。
分别处理完两个链表后再进行l3链表对l1,l2中元素的连接。
#include <iostream>
using namespace std;
typedef struct Node{
int data;
Node* next;
}node,*LinkList;
int main() {
LinkList l1 = new node,l2 = new node,l3 = new node;
l1->next = NULL;
l2->next = NULL;
l3->next = NULL;
int x;
node* p = l1;
while((cin>>x)&&x!=-1){
node* s = new node;
s->data = x;
s->next = NULL;
p->next = s;
p = p->next;
}
p = l2;
while((cin>>x)&&x!=-1){
node* s = new node;
s->data = x;
s->next = NULL;
p->next = s;
p = p->next;
}
p = l1->next;
node* p2 = l2->next;
node* p3 = l3;
if(p==NULL){
l3 = l2->next;
}else if(p2==NULL){
l3 = l1->next;
}else{
node* q = p->next;
while(p&&q){//解决l1链表的相同元素问题,对重复项进行预先处理
if(p->data == q->data){
q = p->next;
p->next = q->next;
q = q->next;
}else{
p = p->next;
q = q->next;
}
}
q = p2->next;
while(p2&&q){//解决l2链表的相同元素问题
if(p2->data == q->data){
q = p2->next;
p2->next = q->next;
q = q->next;
}else{
p2 = p2->next;
q = q->next;
}
}
p = l1->next;
p2 = l2->next;
while(p!=NULL&&p2!=NULL){
if(p->data == p3->data)//排除l3和l1有重复的元素
p = p->next;
if(p2->data == p3->data)//排除l3和l2有重复的元素
p2 = p2->next;
if((p->data)<=(p2->data)){
p3->next = p;
p3 = p;
p = p->next;
}else{
p3->next = p2;
p3 = p2;
p2 = p2->next;
}
}
if(p){
if(p->data!=p3->data)
while (p) {
p3->next = p;
p = p->next;
}
else{
p = p->next;
while (p) {
p3->next = p;
p = p->next;
}
}
}
// p3->next = p;
else if(p2){
if(p2->data!=p3->data)
while (p2) {
p3->next = p2;
p2 = p2->next;
}
else{
p2 = p2->next;
while (p2) {
p3->next = p2;
p2 = p2->next;
}
}
}
}
p3 = l3;
p3 = p3->next;
if(p3==NULL){
cout<<"NULL";
}else{
while(p3!=NULL){
if(p3->next == NULL)
cout<<p3->data;
else
cout<<p3->data<<" ";
p3 = p3->next;
}
}
return 0;
}
第二个方法:(没那么麻烦)
对l1,l2链表的重复项不进行预先的处理,直接在l3连接时通过比较p1->data 是否等于p3->data,若等于则
p1 = p1->next
#include <iostream>
using namespace std;
typedef struct Node{
int data;
Node* next;
}Node,*LinkList;
int main(){
LinkList l1 = new Node,l2 = new Node ,l3 = new Node;
l1->next = NULL;
l2->next = NULL;
l3->next = NULL;
int x;
Node* p = l1;
while(cin>>x&&x!=-1)
{
Node* s = new Node;
s->data = x;
s->next = NULL;
p->next = s;
p = p->next;
}
p = l2;
while(cin>>x&&x!=-1){
Node* s = new Node;
s->data = x ;
s->next = NULL;
p->next = s;
p = p->next;
}
p = l1->next;
Node* p2 = l2->next;
Node* p3 = l3;
while(p&&p2){
if(p->data <= p2->data){//取小的
if(p->data != p3->data){//比较是否l3与l1有重复的元素
p3->next = p;
p3 = p;
p = p->next;
p3->next = NULL;
}else{//若重复相等则跳过下一个节点
p = p->next;
}
}else{
if(p2->data != p3->data){//比较是否l3与l2有重复的元素
p3->next = p2;
p3 = p2;
p2 = p2->next;
p3->next = NULL;
}else{//若重复相等则跳过下一个节点
p2 = p2->next;
}
}
}
if(p){
while (p) {
if(p->data!=p3->data){
p3->next = p;
p3 = p;
p = p->next;
p3->next = NULL;
}else{
p = p->next;
}
}
}
else if(p2){
while (p2) {
if((p2->data!=p3->data)){
p3->next = p2;
p3 = p2;
p2 = p2->next;
p3->next = NULL;//防止最后一个重复
}else{
p2 = p2->next;
}
}
}
p3 = l3;
p3 = p3->next;
if(p3==NULL){
cout<<"NULL";
}else{
while(p3!=NULL){
if(p3->next == NULL)
cout<<p3->data;
else
cout<<p3->data<<" ";
p3 = p3->next;
}
}
return 0;
}