合并两个有序链表

思路(非递归):

  • 合并成一个新的链表
  • 用两个指针指向原来两个链表,用一个指针指向合并的新链表的尾部
  • 比较两个链表元素的大小
  • 核心代码
p3->next=p1;
p3=p1;
p1=p1->next;

 

1.插入元素

struct data* insert(struct data* head,struct data* p0)//有序
{
    struct data* p1=head,*p2;
    if(head==NULL)
    {
        head=p0;
        p0->next=NULL;
    }
    else
    {
            while(p0->data>p1->data&&p1->next!=NULL)
        {
            p2=p1;
            p1=p1->next;
        }
        if(p0->data<=p1->data)//插在头前或中间
        {
            if(p1==head)
                head=p0;
            else
                p2->next=p0;
            p0->next=p1;
        }
        else//插在尾后
        {
            p1->next=p0;
            p0->next=NULL;
        }
    }
    n++;
    return head;
}

 

2.创建单向有序链表

struct data* creat()
{
    struct data* head=NULL,*p;
    p=(struct data*)malloc(LEN);
    printf("Please input data:(end with 0)\n");
    scanf("%d",&p->data);
    while(p->data)
    {
        head=insert(head,p);//插入后要赋值给head
        p=(struct data*)malloc(LEN);
        scanf("%d",&p->data);
    }
    free(p);
    return head;
}

 

3.打印链表

void print(struct data* head)
{
    struct data* p=head;
    if(head==NULL)
        printf("List is NULL.\n");
    else
    {
        printf("Now,there are datas:\n");
        do
        {
            printf("%d->",p->data);
            p=p->next;
        }while(p->next!=NULL);
        printf("%d\n",p->data);
    }
}

 

4.合并两个有序链表

struct data* merge(struct data* head1,struct data* head2,struct data* head3)
{
    struct data* p1=head1,*p2=head2,*p3=head3;
    if(head1==NULL) return head2;
    if(head2==NULL) return head1;
    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->data<p2->data)
        {
            p3->next=p1;
            p3=p1;
            p1=p1->next;
        }
        else
        {
            p3->next=p2;
            p3=p2;
            p2=p2->next;
        }
    }
    p3->next=(p1!=NULL)?p1:p2;
    head3=head3->next;
    return head3;
}

 

 完整代码

#include<stdio.h>
#include<malloc.h>
#define LEN sizeof(struct data)
struct data{
    int data;
    struct data* next;
};
int n=0;
struct data* creat();
void print(struct data* head);
struct data* insert(struct data* head,struct data* p);
struct data* merge(struct data* head1,struct data* head2,struct data* head3);
int main()
{
    struct data* head1,*head2,*head3;
    head3=(struct data*)malloc(20*LEN);//一定要给heads开辟空间
    head1=creat();
    printf("List1:\n");
    print(head1);
    head2=creat();
    printf("List2:\n");
    print(head2);
    printf("After merging:\n");
    head3=merge(head1,head2,head3);
    print(head3);
    return 0;
}

struct data* insert(struct data* head,struct data* p0)//有序
{
    struct data* p1=head,*p2;
    if(head==NULL)
    {
        head=p0;
        p0->next=NULL;
    }
    else
    {
            while(p0->data>p1->data&&p1->next!=NULL)
        {
            p2=p1;
            p1=p1->next;
        }
        if(p0->data<=p1->data)//插在头前或中间
        {
            if(p1==head)
                head=p0;
            else
                p2->next=p0;
            p0->next=p1;
        }
        else//插在尾后
        {
            p1->next=p0;
            p0->next=NULL;
        }
    }
    n++;
    return head;
}

struct data* creat()
{
    struct data* head=NULL,*p;
    p=(struct data*)malloc(LEN);
    printf("Please input data:(end with 0)\n");
    scanf("%d",&p->data);
    while(p->data)
    {
        head=insert(head,p);//插入后要赋值给head
        p=(struct data*)malloc(LEN);
        scanf("%d",&p->data);
    }
    free(p);
    return head;
}

void print(struct data* head)
{
    struct data* p=head;
    if(head==NULL)
        printf("List is NULL.\n");
    else
    {
        printf("Now,there are datas:\n");
        do
        {
            printf("%d->",p->data);
            p=p->next;
        }while(p->next!=NULL);
        printf("%d\n",p->data);
    }
}

struct data* merge(struct data* head1,struct data* head2,struct data* head3)
{
    struct data* p1=head1,*p2=head2,*p3=head3;
    if(head1==NULL) return head2;
    if(head2==NULL) return head1;
    while(p1!=NULL&&p2!=NULL)
    {
        if(p1->data<p2->data)
        {
            p3->next=p1;
            p3=p1;
            p1=p1->next;
        }
        else
        {
            p3->next=p2;
            p3=p2;
            p2=p2->next;
        }
    }
    p3->next=(p1!=NULL)?p1:p2;
    head3=head3->next;
    return head3;
}
View Code

 

递归版

struct data* merge(struct data* head1,struct data* head2)//用递归
{
    struct data* p1=head1,*p2=head2;
    if(head1==NULL) return head2;
    if(head2==NULL) return head1;
    if(p1->data<p2->data)
       {
           p1->next=merge(p1->next,p2);
           return head1;
       }
    else
        {
            p2->next=merge(p1,p2->next);
            return head2;
        }
}

 

写链表会碰到的问题

  • 调用函数的返回值是指针,需要赋给头指针
  • 动态创建链表需要开辟新空间,结束要free没用了的指针

 

posted @ 2020-12-20 13:42  inss!w!  阅读(138)  评论(0编辑  收藏  举报