pta 7-3 两个有序链表序列的交集

本题要求

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。

裁判测试程序样例

除了simple之外,我估计测试点还有如下
出现多个相同数据
相同数据在开头结尾
是否升序
大量数据
链表为空
个人意见,不确定

输入样例:

1 2 5 -1
2 4 5 8 10 -1

输出样例:

2 5

我一开始的代码

思路是链表一向后遍历,每一个节点去链表二里比较。

出现了最后一个测试点运行超时的情况,应该是大量数据输入。

#include <stdio.h>
#include <stdlib.h>
typedef struct list{
    int num;
    struct list *next;
}List;
List *creative();
List *together(List *head1,List *head2);
int main() {
    int flag=1;
    List *head1,*head2,*head,*p;
    head1=creative();
    head2=creative();
    head=together(head1,head2);
    p=head;
    if(p==NULL){
        printf("NULL");
        return 0;
    }
    while(p){
        List *q=p;
        if(flag){
            printf("%d",p->num);
            flag=0;
        } else{
            printf(" %d",p->num);
        }
        p=p->next;
        free(q);
    }
    return 0;
}
List *creative(){
    int num;
    List *p=NULL,*last,*head=NULL;
    head=NULL;
    while (1){
        scanf("%d",&num);
        if(num>0){
            p=(List*)malloc(sizeof (List));
            p->num=num;
            p->next=NULL;
            if(head!=NULL){
                last->next=p;
            } else{
                head=p;
            }
            last=p;
        } else{
            return head;
        }
    }
}
List *together(List *head1,List *head2){
    List *head=(List*) malloc(sizeof (List)),*p,*q,*temp,*last=NULL;
    head->next=NULL;
    int flag=1,tag;
    p=head2;
    while(head1){
        if(head1)temp=head1->next;
        while(p){
            tag=1;
            if(head1->num==p->num){
                q=(List*) malloc(sizeof (List));
                q->num=p->num;
                q->next=NULL;
                if(flag){
                    head->next=q;
                    flag=0;
                } else{
                    last->next=q;
                }
                last=q;
                break;
                tag=0;
            }
            p=p->next;
        }
        if(tag){
            p=head2;
        }else{
            head2=p;
        }
        head1=temp;
    }
    return head->next;
}

改进后

根据题目,两个输入链表都是升序链表,所以遍历时已经比较过的数据是不需要再遍历的,我这里用的是两个数据先比较,数据较小的链表往后遍历,新链表输出创建,可以是创建一个新的(我这里就是),也可以是借助原链表的空间,重新组合(不知道是不是这么表述,但是我是这么理解的)。

#include <stdio.h>
#include <stdlib.h>
typedef struct list{
    int num;
    struct list *next;
}List;
List *creative();
List *together(List *head1,List *head2);
int main() {
    int flag=1;
    List *head1,*head2,*head,*p;
    head1=creative();
    head2=creative();
    head=together(head1,head2);
    p=head;
    if(p==NULL){
        printf("NULL");
        return 0;
    }
    while(p){
        List *q=p;
        if(flag){
            printf("%d",p->num);
            flag=0;
        } else{
            printf(" %d",p->num);
        }
        p=p->next;
        free(q);
    }
    return 0;
}
List *creative(){
    int num;
    List *p=NULL,*last,*head=NULL;
    head=NULL;
    while (1){
        scanf("%d",&num);
        if(num>0){
            p=(List*)malloc(sizeof (List));
            p->num=num;
            p->next=NULL;
            if(head!=NULL){
                last->next=p;
            } else{
                head=p;
            }
            last=p;
        } else{
            return head;
        }
    }
}
List *together(List *head1,List *head2){
    List *head=(List*) malloc(sizeof (List)),*p,*last=NULL;
    head->next=NULL;
    while (head1&&head2){
        if(head1->num==head2->num){
            p=(List*) malloc(sizeof (List));
            p->num=head2->num;
            p->next=NULL;
            if(head->next){
                last->next=p;
            } else{
                head->next=p;
            }
            last=p;
            head1=head1->next;
            head2=head2->next;
        } else if(head1->num<head2->num){
            head1=head1->next;
        } else if(head1->num>head2->num){
            head2=head2->next;
        }
    }
    return head->next;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值