两个有序链表合并(新表不含重复元素)(记录学习过程

两个有序链表合并(新表不含重复元素)(记录学习过程)

题目:
已知两个非降序链表序列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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值