已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。
输入格式:
输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。
输出格式:
在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL。
输入样例:
1 3 5 -1
2 4 6 8 10 -1
输出样例:
1 2 3 4 5 6 8 10
第一次链表的实现。之前看链表,啥空表头的链表,双向,循环链表,感觉会,然后实现才发现,有点难呀。
第一次写的错误代码,超时了。
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int dat;
struct Node *pre;
struct Node *next;
};
typedef struct Node node;
node *headl;
node *make_new_node(node *head,int data)
{
node *p,*tep=head;
p=(node*)malloc(sizeof(node));
if(p==NULL)
{
exit(0);
}
if(head==NULL)//first node
{
head=p;
head->dat=data;
head->pre=NULL;
head->next=NULL;
}
else
{
tep=head;
while(tep->next!=NULL)
{
tep=tep->next;
}**这里可以优化**
tep->next=p;
p->dat=data;
p->pre=tep;
p->next=NULL;
}
return head;
}
int get_merge(node *head1,node *head2)
{
node *pos1,*pos2;
//here,we put head1 as a new node's first head;
if(head1==NULL&&head2==NULL)
{
return 0;//输出null;
}
if(head1==NULL||head2==NULL)
{
return 1;//只需输出一个链表的值
}
int t1=head1->dat,t2=head2->dat;
**下面判断这么复杂,就是因为最后一个节点的null,无法有效的解决**
if(t1>t2)
{
headl=head2;
while(1)
{
t1=head1->dat,t2=head2->dat;
if(t1>t2)
{
if(head2->next==NULL)
{
head2->next=head1;
break;
}
else
head2=head2->next;
}
else if(t1<t2)
{
pos2=head1->next;
head2->pre->next=head1;
head1->next=head2;
head1=pos2;
}
else
{
pos1=head1->next;
pos2=head2->next;
head1->next=head2;
head2->next=pos1;
head2=pos2;
if(head1==NULL) break;
}
}
}
else
{
headl=head1;
while(1)
{
t1=head1->dat,t2=head2->dat;
if(t2>t1)
{
if(head1->next==NULL)
{
head1->next=head2;
break;
}
else
head1=head1->next;
}
else if(t2<t1)
{
pos2=head2->next;
head1->pre->next=head2;
head2->next=head1;
head2=pos2;
}
else
{
pos1=head1->next;
pos2=head2->next;
head1->next=head2;
head2->next=pos1;
head2=pos2;
if(head2==NULL) break;
}
}
}
return 2;
}
void dis_link(node *head)
{
node *p=head,*pr;
while(p->next!=NULL)
{
printf("%d ",p->dat);
p=p->next;
}
printf("%d\n",p->dat);
}
void free_node(node *head)
{
node *p;
node *pr=head;
while(pr->next!=NULL)
{
p=pr->next;
free(pr);
pr=p;
}
free(pr);
}
int main(void)
{
node *head1=NULL,*head2=NULL;
int data;
while(scanf("%d",&data)&&data!=-1)
{
head1=make_new_node(head1,data);
}
while(scanf("%d",&data)&&data!=-1)
{
head2=make_new_node(head2,data);
}
int flag=get_merge(head1,head2);
if(flag==1)
{
if(head1==NULL)
{
dis_link(head2);
free_node(head2);
}
else
{
dis_link(head1);
free_node(head1);
}
}
else if(flag==0)
{
printf("NULL\n");
}
else
{
dis_link(headl);
free_node(headl);
}
return 0;
}
带了空头结点简单多了
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int dat;
struct Node *next;
};
typedef struct Node node;
node *headp;
node *make_new_node(node *head)
{
**这里改为只建立一个空头结点**
node *p;
p=(node*)malloc(sizeof(node));
head=p;
p->next=NULL;
return head;
}
int get_merge(node *head1,node *head2)
{
node *pos1,*pos2,*headl;
if(head1->next==NULL&&head2->next==NULL)
{
return 0;//输出null;
}
if(head1->next==NULL||head2->next==NULL)
{
return 1;//只需输出一个链表的值
}
pos1=(node*)malloc(sizeof(node));
headl=pos1;
headp=headl;
**开始以为空头结点不需要开空间**
head1=head1->next;
head2=head2->next;
**这里的空头结点很有用。**
while(head1&&head2)
{
if(head1->dat<head2->dat)
{
headl->next=head1;
head1=head1->next;
}
else
{
headl->next=head2;
head2=head2->next;
}
headl=headl->next;
}
if(!head1&&!head2) return 2;
if(head1!=NULL)
{
headl->next=head1;
}
if(head2!=NULL)
{
headl->next=head2;
}
return 2;
}
void dis_link(node *head)
{
node *p=head->next,*pr;
while(p->next!=NULL)
{
printf("%d ",p->dat);
p=p->next;
}
printf("%d\n",p->dat);
}
void free_node(node *head)
{
node *p;
node *pr=head;
while(pr->next!=NULL)
{
p=pr->next;
free(pr);
pr=p;
}
free(pr);
}
int main(void)
{
node *head1=NULL,*head2=NULL;
head1=make_new_node(head1);
head2=make_new_node(head2);
int data;
node *ll=head1;
while(scanf("%d",&data),data!=-1)
{
node *tep;
tep=(node*)malloc(sizeof(node));
ll->next=tep;
tep->next=NULL;
tep->dat=data;
ll=tep;**这里就是上面的优化,不需要移动头结点去添加新的节点了**
}
ll=head2;
while(scanf("%d",&data),data!=-1)
{
node *tep;
tep=(node*)malloc(sizeof(node));
ll->next=tep;
tep->next=NULL;
tep->dat=data;
ll=tep;
}
int flag=get_merge(head1,head2);
if(flag==1)
{
if(head1==NULL)
{
dis_link(head2);
free_node(head2);
}
else
{
dis_link(head1);
free_node(head1);
}
}
else if(flag==0)
{
printf("NULL\n");
free_node(head1);
free_node(head2);
}
else
{
dis_link(headp);
free_node(headp);
}
return 0;
}
收获:讲得好不如做得好,代码自己实现起来,能够加深印象。
链表不同于数组,如果此题用数组,开三个。而链表开两个链表,然后在开一个控表头,把其他的数据块链接到空表头后面即可。不需要再开空间