1.算法思路
- 将两单链表合并,常用的方法是归并排序。每次比较两个链表的当前结点值,选择较大的结点值进行插入操作。
- 由于是将递减有序的链表变为递增有序的链表,那么可以考虑使用头插法,每次归并排序比较完成后将更大值的结点插入到已排序链表中,然后移动排序链表的头指针指向该结点。
2.定义结构体
typedef struct LNode {
int data;
struct LNode *next;
} LNode, *LinkList;
3.定义函数
3.1 创建单链表
编写函数创建单链表。输入参数为:
- LinkList A: 单链表的头结点
- int a[]: 该单链表的元素值
- length: 元素值的长度
当i < length时,循环创建结点,并使用尾插法将结点插入到当前链表的最后面,然后将链表尾指针移动至尾部,即当前结点。
void CreateList(LinkList A, int a[], int length) {
LNode *s = (LNode *)malloc(sizeof(LNode));
LNode *tail = A;
s->next = NULL;
for(int i=0; i < length; i++) {
s = (LNode *)malloc(sizeof(LNode));//创建新结点
s->data = a[i];
s->next = NULL;
tail->next = s;
tail = tail->next;
}
}
3.2 合并单链表
- 首先创建链表头结点C,它将指向已排好序的链表头结点,每次使用头插法插入新结点后都将指向此时的头结点,即新结点。
- 创建工作指针p,q分别指向A和B的首个数据结点。判断p,q是否为空。如果有链表为空,则返回NULL。这里假定两个链表都不为空时才进行排序,否则结束程序。
- 当p,q都不为空时,遍历A,B链表,比较结点值,进行如下判断:
- p->data == q->data: 说明两结点值重复,因此选择删除一个结点,头插另一个结点。这里选择插入p结点而删除q结点。首先使用指针s只想当前结点p,然后将p结点向后移动,之后修改相应指针实现p的头插。然后将s指向q,并让q向后移动,再释放s。
- p->data > q->data: 此时选择更大的结点即p将其插入到排序链表中,然后p后移,比较新的p和q。
- p->data < q->data: 此时选择更大的结点即q将其插入到排序链表中,然后q后移,比较新的p和q。
- 当A或B遍历完成时,上述循环退出。此时判断p,q哪个指针为空。使用头插法将未空指针后面的剩余结点插入到排序链表。
LinkList MergeList(LinkList A, LinkList B) {
//C用于指向以合并链表的头结点
LinkList C = (LinkList)malloc(sizeof(LNode));
C->next = NULL;
//p,q用于遍历两个链表,s用于指向当前结点更大的结点
LNode *p = A->next, *q = B->next, *s = NULL;
if(!p || !q) {
printf("链表为空!\n");
return NULL;
}
while(p && q) {
//p,q都不为空,开始比较
if(p->data == q->data) {
//p,q相等,删除一个结点
//首先将一个结点头插到当前链表中
s = p;
p = p
合并递减单链表实现递增有序

最低0.47元/天 解锁文章
268

被折叠的 条评论
为什么被折叠?



