题目:假设有两个按元素值递增次序排列的线性表,均以单链表的形式存储。请编写算法将这两个单链表归并为一个按元素值递减次序排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
关键字:带头结点单链表 + 就地归并 + 改序
思路
1.利用**原来两个单链表的结点*:将A的表头摘下,作为新表的表头
两个链表已经按元素值递增次序排序,将其合并时,均从第一个结点进行比较,将小的结点连入链表中,同时后移工作指针。
**思路来源:**可以通过最终目的倒推得到:最终得到的新链表一定是包含两个原链表中所有元素,并且降序排列,而原来两表都是递增排列,所以作为只能单向扫描的单链表,每次前进扫描得到的元素都在增加,所以首先考虑头插法,(大的放在最前面),
越小的元素越早进行头插,所以可以直接两表同时扫描,每次得到当前扫描位置下最小的元素(也就是两表并集中最小的元素)率先进行头插操作
需要变量:La,Lb,各自的遍历工作指针pa,pb
新表中头插法小助手r,因为每次只插入一个元素,所以只设立一个后继指针
(该问题要求结果链表按元素值递减次序排列,故新链表的建立应该采用头插法。)
2.比较结束后,可能会有一个链表非空,剩下的都是大于另一链表所有元素的元素了,头插法连入新链表
**小技巧:**为了避免重复写出A表非空和B表非空两种情况,可以利用谁剩余谁用b的指针,来减少写A剩余的情况,一个B情况就够用了
void MergeList(LinkList &La,LinkList &Lb){
LNode*pa=La->next,*pb=Lb->next;*r
La->next=NULL;
while(pa&&pb){
if(pa->data<=pb->data){//将AB两表中较小值通过头插法插入新表
r=pa->next;
pa->next=La-next;
La->next=pa;
pa=r;
}
else{
r=pb->next;
pb->next=La-next;
La->next=pb;
pb=r;
}
if(pa)
pb=pa;
while(pb){//处理剩下的一个非空链表
r=pb->next;//依次插入到La中,头插法
pb->next=La-next;
La->next=pb;
pb=r;
}
free(Lb);
}
}