题目1:
将2个递增的有序链表合并为一个链表的有序链表; 要求结果链表仍然使⽤用两个链表的存储空间,不另外占用其他的存储空间. 表中不允许有重复的数据。
算法思路:
假设待合并的链表为La和Lb,合并后的新表使用头指针Lc(Lc的表头结点设为La的表头结点)指向. Pa 和 Pb 分别是La,Lb的工作指针.初始化为相应链表的首元结点,Pc为指向Lc表的工作指针,初始值为Lc的头结点;
从首元结点开始比较, 当两个链表La 和Lb 均未到达表尾结点时,依次摘取其中较小值重新链表在Lc表的最后;
如果两个表中的元素相等,只摘取La表中的元素,删除Lb表中的元素,这样确保合并后表中无重复的元素;
当一个表达到表尾结点为空时,非空表的剩余元素直接链接在Lc表最后.
最后释放链表Lb的头;
复杂度分析:
时间复杂度:O(n);
代码实现:
void MergeList(LinkList *La, LinkList *Lb, LinkList *Lc){
LinkList pa, pb, pc,temp;
// pa指向链表a的首元结点
pa = (*La)->next;
// pb指向链表b的首元结点
pb = (*Lb)->next;
// pc指向Lc的头结点Lc的头结点就是La
pc = *Lc = *La;
while (pa && pb) {
if (pa->data < pb->data) {
// 取较小的那个插入Lc表
pc->next = pa;
// Lc表的指针前移
pc = pa;
pa = pa->next;
} else if (pa->next > pb->next) {
pc->next = pb;
// Lc表的指针前移
pc = pb;
pb = pb->next;
} else {//相等
// 取一个插入Lc中,另外一个释放掉
pc->next = pa;
// Lc表的指针前移
pc = pa;
pa = pa->next;
// 用temp记录多余的结点
temp = pb;
pb = pb->next;
free(temp);
}
}
// 剩余的结点直接拼接在后面
pc->next = pa ? pa : pb;
// 将另外一个表的头结点释放掉
free(*Lb);
}
复制代码
题目2:
已知两个链表A和B分别表示两个集合.其元素递增排列. 设计一个算法,用于求出A与B的交集,并存储在A链表中; 例如 : La = {2,4,6,8}; Lb = {4,6,8,10}; Lc = {4,6,8}
算法思路:
La,Lb。Lc为La的头结点;