有序链表的合并和删除

#include<stdio.h>
#include<stdlib.h>
struct node;
typedef int datatype;
typedef struct node *pnode;
struct node
{
    datatype info;
    pnode link;
};
typedef struct node *linklist;
linklist createnulllist()
{
    linklist head=(linklist)malloc(sizeof(struct node));
    if(head) head->link=NULL;
    else printf("创建空链表失败\n");
    return head;
}
//尾插法建立单链表
pnode createlinklist(linklist head)
{
    pnode p=NULL;
    pnode rear=head;
    int data;
    scanf("%d",&data);
    while(data!=-1)
    {
        p=(linklist)malloc(sizeof(struct node));
        if(p)
        {
            p->info=data;
            p->link=NULL;
            rear->link=p;
            rear=p;
            scanf("%d",&data);
        }
    }
    printf("尾插法建立链表成功\n\n");
    return head;
}

//合并LIST1和LIST2链表
pnode add(linklist LIST1,linklist LIST2,linklist LIST3)
{
    linklist p1=LIST1->link,p2=LIST2->link;                //因为头结点里面没有数值,所以要这样
    linklist rear,p3=NULL;
    rear=LIST3;
    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->info<p2->info)
        {
            p3=(linklist)malloc(sizeof(struct node));
            p3->info=p1->info;
            rear->link=p3;
            rear=p3;
            p1=p1->link;
        }
        else if(p1->info==p2->info)
        {
            p3=(linklist)malloc(sizeof(struct node));
            p3->info=p1->info;
            rear->link=p3;
            rear=p3;
            p1=p1->link;
            p3=(linklist)malloc(sizeof(struct node));
            p3->info=p2->info;
            rear->link=p3;
            rear=p3;
            p2=p2->link;
        }
        else
        {
            p3=(linklist)malloc(sizeof(struct node));
            p3->info=p2->info;
            rear->link=p3;
            rear=p3;
            p2=p2->link;
        }
    }
    while(p1!=NULL)
    {
        p3=(linklist)malloc(sizeof(struct node));
        p3->info=p1->info;
        rear->link=p3;
        rear=p3;
        p1=p1->link;
    }
    while(p2!=NULL)
    {
        p3=(linklist)malloc(sizeof(struct node));
        p3->info=p2->info;
        rear->link=p3;
        rear=p3;
        p2=p2->link;
    }
    rear->link=NULL;                     //要让两个都要指向空,不然输出会陷入死循环中
    p3->link=NULL;
    return LIST3;
}

//删除值相同的结点,只保留一个
pnode deletelist(linklist LIST3,int n)
{
    linklist q,p,head;
    head=LIST3;
    q=LIST3;
    p=head->link;
    int i=0;
    while(p!=NULL)                 //记录有几个值相同的结点
    {
        if(p->info==n)
        {    
            p=p->link;
            i++;
        }
        else p=p->link;
    }
    if(i==0) printf("LIST3里面没有该数值\n\n");
    p=head->link;                               //重新让p指向开头
    while(p!=NULL)                            //i如果等于1就证明只有一个该数值的结点,就不用删除
    {

        if(i==0) break;
        else if(i==1) break;
        else
        {
            if(p->info==n)
            {
                q->link=p->link;
                free(p);
                p=q->link;
                i--;
            }
            else p=p->link,q=q->link;
        }
    }
    return LIST3;
}
//输出链表
void print(linklist head)
{
    linklist p=head->link;
    while(p!=NULL)
    {
        printf("%4d",p->info);
        p=p->link;
    }
    printf("\n");
}
int main()
{
    linklist LIST1,LIST2,LIST3;
    int data,num;
    LIST1=createnulllist();
    LIST2=createnulllist();
    LIST3=createnulllist();
    printf("请输入递增有序的顺序输入LIST1的数据,以-1结束\n\n");
    LIST1=createlinklist(LIST1);
    printf("输出建立的链表\n\n");
    print(LIST1);
    printf("请输入递增有序的顺序输入LIST2的数据,以-1结束\n\n");
    LIST2=createlinklist(LIST2);
    printf("输出建立的链表\n\n");
    print(LIST2);
    printf("输出合并了LIST1和LIST2的LIST3为:\n\n");
    LIST3=add(LIST1,LIST2,LIST3);
    print(LIST3);
    while(1)
    {
        printf("1:**********删除值*******\n");
        printf("0:**********退出程序*****\n");
        scanf("%d",&num);
        switch(num){
        case 1:printf("请输入你想要删除的LIST3中的数值\n");
            scanf("%d",&data);
            printf("\n\n");
            deletelist(LIST3,data);
            printf("输出删除值后的LIST3\n\n");
            print(LIST3);
            continue;
        case 0:return 0;
        default:printf("输入指令错误\n");
        }
    }
    system("pause");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值