一、【问题描述】
A 和B是两个单链表(带表头结点),其中元素递增有序。设计一个算法,将A和B归并成一个按元素值非递减有序的链表C, C由A和B中的结点组成。
二、【问题分析】
已知A、B中的元素递增有序,要使归并后的C中元素依然有序,可以从A、B中挑出最小的元素插入C的尾部,这样当A. B中的所有元素都插入C中时,C - -定是递增有序的。哪一个元素是A、B中最小的元素呢?很明显,由于A、B是递增的,因此A中的最小元素是其开始结点中的元素,B也一样。只需从A. B的开始结点中选出一个较小的来插入C的尾部即可。这里还需注意,A与B中的元素有可能一个已经全部被插入到C中,另一个还没有插完,如A中所有元素已经全部被插入到C中,而B
还没有插完,这说明B中的所有元素都大于C中的元素,因此只要将B链接到C的尾部即可。如果A没有插完,则用类似的方法来解决。
三、【问题解答】
void merge(LNode *A,LNode *B,LNode *&C){
LNode *p=A->next;
LNode *q=B->next;
LNode *r;
C=A;
C->next=NULL;
free(B);
r=C;
while(p!=NULL&&q!=NULL){
if(p->data<=q->data){
r->next=p;
p=p->next;
r=r->next;
}
else{
r->next=q;q=q->next;
r=r->next;
}
}
r->next=NULL;
if(p!=NULL) r->next=p;
if(q!=NULL) r->next=q;
}
ps:【问题拓展】
如果将归并成一个递增的链表C改为归并成一个递减的链表C,那要如何解决?
【解析与解答】
只要将插入过程改成头插法即可解决,这里不需要r追踪C的终端结点而是用s来接收新的结点,插入链表C的前端。
归并成递减的单链表的算法代码如下:
void merge(LNode *A,LNode *B,LNode *&C){
LNode *p=A-next;
LNode *q=B->next;
LNode *s;
C=A;
C->next=NULL;
free(B);
while(p!=NULL&&q!=NULL){
if(p->data<=q->data){
s=p;
p=p->next;
s->next=C->next;
C->next=s;
}
else{
s=q;
q=q->next;
s->next=C->next;
C->next=s;
}
}
while(p!=NULL){
s=p;
p=p->next;
s->next=C->next;
C->next=s;
}
while(q!=NULL){
s=q;
q=q->next;
s->next=C->next;
C->next=s;
}
}