题目描述:假设有两个按元素值递增次排列的线性表,均以单链表形式存储。请编与算法将这两个单链表归并为一个按元素值依次递减排列的单链表,并要求利用原来两个单链表的结点存放归并后的单链表。
算法思想:
1.初始化:
创建一个新的头结点(用于结果链表)。
定义指针 p 和 q 分别遍历两个链表。
使用头插法将节点插入结果链表(确保递减顺序)。
2.归并过程:
比较 p 和 q 的当前节点值,选择较大者插入结果链表的头部。
移动对应的指针(p 或 q)到下一个节点。
重复上述步骤,直到其中一个链表遍历完毕。
3.处理剩余节点:
将未遍历完的链表剩余节点依次头插到结果链表中。
4.返回结果:
返回新链表的头结点。
复杂度分析:
时间复杂度:O(n + m),其中 n 和 m 分别是两个链表的长度。需要遍历所有节点。
空间复杂度:O(1),仅使用常数个额外指针变量,复用原节点。
代码实现:
#include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *next; } Node, *LinkedList; // 创建递增链表 LinkedList createList() { LinkedList L = (LinkedList)malloc(sizeof(Node)); L->next = NULL; Node *tail = L; int x; printf("输入递增序列(以-1结束):"); while (scanf("%d", &x), x != -1) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = x; newNode->next = NULL; tail->next = newNode; tail = newNode; } return L; } // 归并两个递增链表为递减链表 LinkedList mergeDescending(LinkedList La, LinkedList Lb) { LinkedList Lc = (LinkedList)malloc(sizeof(Node)); // 结果链表的头结点 Lc->next = NULL; Node *p = La->next; // 遍历 La Node *q = Lb->next; // 遍历 Lb while (p != NULL && q != NULL) { if (p->data <= q->data) { // 头插法插入 p Node *next = p->next; p->next = Lc->next; Lc->next = p; p = next; } else { // 头插法插入 q Node *next = q->next; q->next = Lc->next; Lc->next = q; q = next; } } // 处理剩余节点 while (p != NULL) { Node *next = p->next; p->next = Lc->next; Lc->next = p; p = next; } while (q != NULL) { Node *next = q->next; q->next = Lc->next; Lc->next = q; q = next; } // 释放原链表的头结点(可选) free(La); free(Lb); return Lc; } // 打印链表 void printList(LinkedList L) { Node *p = L->next; while (p != NULL) { printf("%d ", p->data); p = p->next; } printf("\n"); } int main() { printf("创建链表 La:\n"); LinkedList La = createList(); printf("创建链表 Lb:\n"); LinkedList Lb = createList(); printf("La: "); printList(La); printf("Lb: "); printList(Lb); LinkedList Lc = mergeDescending(La, Lb); printf("归并后的递减链表 Lc: "); printList(Lc); return 0; }