18064 链表的有序合并

18064 链表的有序合并
Description
已知有两个链表a和b,结点类型相同,均包括一个int类型的数据。编程把两个链表合并成一个,结点按升序排列。

#include “stdio.h”
#include “malloc.h”
#define LEN sizeof(struct DATA)

struct DATA
{
long num;
struct DATA *next;
};

struct DATA *create(int n)
{
struct DATA *head=NULL,*p1=NULL,*p2=NULL;
int i;
for(i=1;i<=n;i++)
{ p1=(struct DATA *)malloc(LEN);
scanf(“%ld”,&p1->num);
p1->next=NULL;
if(i==1) head=p1;
else p2->next=p1;
p2=p1;
}
return(head);
}

struct DATA *merge(struct DATA *head, struct DATA *head2)
{
_______________________
return head;
}

struct DATA *insert(struct DATA *head, struct DATA *d)
{
_______________________
return head;
}

struct DATA *sort(struct DATA *head)
{
_______________________
return head;
}

void print(struct DATA *head)
{
struct DATA *p;
p=head;
while(p!=NULL)
{
printf(“%ld”,p->num);
p=p->next;
printf(“\n”);
}
}

main()
{
struct DATA *head, *head2;
int n;
long del_num;
scanf(“%d”,&n);
head=create(n);
scanf(“%d”,&n);
head2=create(n);
head = merge(head, head2);
head = sort(head);
print(head);
}

输入格式
第一行一个数n,表示第一个列表的数据个数
每二行为n个数
第三行为一个数m
第四行为m个数

输出格式
输出合并后的有序的数据,一行一个数

输入样例
2
4 8
3
9 1 5

输出样例
1
4
5
8
9

完整代码:

#include <iostream>
#include <queue>
#include "malloc.h"
#define LEN sizeof(struct DATA)

using namespace std;

struct DATA
{
     long num;
     struct DATA *next;
};

struct DATA *create(int n)
{
     struct DATA *head=NULL,*p1=NULL,*p2=NULL;
     int i;
     for(i=1;i<=n;i++)
     {  p1=(struct DATA *)malloc(LEN);
        scanf("%ld",&p1->num);
        p1->next=NULL;
        if(i==1) head=p1;
        else p2->next=p1;
        p2=p1;
      }
      return(head);
}

struct DATA *merge(struct DATA *head, struct DATA *head2)
{
    struct DATA *p;
    p = head;//因为最后return的是头结点,所以用p来等同头结点,保持头结点的地址不变
    while(p->next != NULL){ //p遍历到链表1的最后,循环找到尾节点  若这里p是head的话是错误的
        p = p->next;
    }
    //循环结束后p代表的是尾节点
    //在尾节点(表1末端)接上表2
    p->next = head2;
    return head;
}

//有序插入结点
struct DATA *insert(struct DATA *head, struct DATA *d)
{
    struct DATA *p;
    p = head;//因为最后return的是头结点,所以用p来等同头结点,保持头结点的地址不变
    if(head == NULL){ //头结点为空,直接范围插入的结点
        return d;//d为表
    }
    else{ //表不为空
        //p1指向的数据一直小于d且p1指向的不是表尾结点时,p1一直向后遍历,循环找d的插入位置
        while(p->next->num < d->num && p != NULL){
            p = p->next;
        }
        //插入
        d->next = p->next;//用d->next存下p->next的地址
        p->next = d;//这时候p->next就可以指向d了,并且d->next指向的是原来的p的next,完成插入
    }
    return head;
}
//链表排序(使用冒泡排序)
struct DATA *sort(struct DATA *head)
{
    struct DATA *i,*j,*p;
    p = head;
    for(i = head;i->next != NULL;i = i->next){
        for(j = head;j->next;j = j->next){
            if(j->num > j->next->num){//j当前的数据>j下一个结点的数据,交换结点中的数据(不用交换结点)
                long t = j->num;//暂存
                j->num = j->next->num;
                j->next->num = t;
            }
        }
    }

    return head;
}

void print(struct DATA *head)
{
    struct DATA *p;
    p=head;
    while(p!=NULL)
    {
        printf("%ld",p->num);
        p=p->next;
        printf("\n");
    }
}

main()
{
    struct DATA *head, *head2;
    int n;
    long del_num;
    scanf("%d",&n);
    head=create(n);
    scanf("%d",&n);
    head2=create(n);
    head = merge(head, head2);
    head = sort(head);
    print(head);
}

错误代码

#include <iostream>
#include <queue>
#include "malloc.h"
#define LEN sizeof(struct DATA)

using namespace std;

struct DATA
{
     long num;
     struct DATA *next;
};

struct DATA *create(int n)
{
     struct DATA *head=NULL,*p1=NULL,*p2=NULL;
     int i;
     for(i=1;i<=n;i++)
     {  p1=(struct DATA *)malloc(LEN);
        scanf("%ld",&p1->num);
        p1->next=NULL;
        if(i==1) head=p1;
        else p2->next=p1;
        p2=p1;
      }
      return(head);
}

struct DATA *merge(struct DATA *head, struct DATA *head2)
{
    struct DATA *p;
    p = head;//因为最后return的是头结点,所以用p来等同头结点,保持头结点的地址不变
    while(p->next != NULL){ //p遍历到链表1的最后,循环找到尾节点  若这里p是head的话是错误的
        p = p->next;
    }
    //循环结束后p代表的是尾节点
    //在尾节点(表1末端)接上表2
    p->next = head2;
    return head;
}

//有序插入结点
struct DATA *insert(struct DATA *head, struct DATA *d)
{
    struct DATA *p0,*p1,*p2;//(p2过渡指针)
    p0 = d;//p0指针指向要插入表中的d
    p1 = head;//p1指向链表表头,//因为最后return的是头结点,所以用p来等同头结点,保持头结点的地址不变
    if(head == NULL){ //表为空,直接插入
        head = p0;
        p0->next = NULL;
    }
    else{ //表不为空
        //p1指向的数据一直小于d且p1指向的不是表尾结点时,p1一直向后遍历
        while(p1->num < p0->num && p1->next != NULL){
            p2 = p1;//p2暂时标记p1当前位置,为了方便找到位置时插入d
            p1 = p1->next;
            //p1的数据比p0(d)大,即找到了p0的插入位置(p1之前,p2后面)
            if(p1->num >= p0->num){
                if(p1 == head){ //如果此时p1指向表头,则p0直接作为表头(最小)
                    head = p0;
                }
                else{ //p1不在表头,p0插入到p2和p1之间
                    p2->next = p0;
                    p0->next = p1;
                }
            }
           //p1指向表尾结点(p->next == NULL),即p0比表中所有元素都大,插入到表尾
           else{
                p1->next = p0;
                p0->next = NULL;
           }
        }
    }
    return head;
}
//链表排序(利用上面的有序插入函数)
struct DATA *sort(struct DATA *head)
{
    struct DATA *p1,*p2;
    p2 = head;
    p1 = head;
    //p2遍历,p1在后面暂存结点
    p2 = p2->next;
    p1->next = NULL;
    p1 = p2;
    while(p2->next != NULL){
        p2 = p2->next;
        p1->next = NULL;
        head = insert(head,p1);//p1移出重新插入(有序)
        p1 = p2;//继续
    }
    //最后一个结点
    head = insert(head,p1);
    return head;
}

void print(struct DATA *head)
{
    struct DATA *p;
    p=head;
    while(p!=NULL)
    {
        printf("%ld",p->num);
        p=p->next;
        printf("\n");
    }
}

main()
{
    struct DATA *head, *head2;
    int n;
    long del_num;
    scanf("%d",&n);
    head=create(n);
    scanf("%d",&n);
    head2=create(n);
    head = merge(head, head2);
    head = sort(head);
    print(head);
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值