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);
}