1、分别创建两个有序的单链表(每个表的元素个数以及每个元素的值在运行时由键盘输入),现将两个单链表合并,并保证新表依然为有序的单链表。
#include <stdio.h>
#include <stdlib.h>
// 定义单链表结构体
typedef struct ListNode {
int data;
struct ListNode *next;
} ListNode;
//创建一个单链表,返回头节点的指针
ListNode* createList() {
ListNode *head = NULL, *p = NULL, *q = NULL;
int n = 0, data = 0;
printf("请输入要创建单链表的长度:");
scanf("%d", &n);
// 依次读入每个元素,创建新的节点,并插入链表尾部
for (int i = 1; i <= n; ++i) {
printf("请输入第%d个节点值:", i);
scanf("%d", &data);
// 创建新节点
p = (ListNode*) malloc(sizeof(ListNode));
p->data = data;
p->next = NULL;
// 插入链表尾部
if (head == NULL) {
head = p;
} else {
q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = p;
}
}
return head;
}
//合并两个有序的单链表,返回合并后的链表头节点的指针
ListNode* mergeLists(ListNode* list1, ListNode* list2) {
if (list1 == NULL) {
return list2;
}
if (list2 == NULL) {
return list1;
}
// 创建哨兵节点,简化代码逻辑
ListNode sentinel = {0, NULL};
ListNode *tail = &sentinel;
// 依次比较两个链表的节点,并将较小的节点插入新的链表尾部
while (list1 != NULL && list2 != NULL) {
if (list1->data <= list2->data) {
tail->next = list1;
list1 = list1->next;
} else {
tail->next = list2;
list2 = list2->next;
}
tail = tail->next;
}
// 将剩余节点插入新链表尾部
if (list1 != NULL) {
tail->next = list1;
}
if (list2 != NULL) {
tail->next = list2;
}
// 返回哨兵节点的下一个节点作为新链表头节点
return sentinel.next;
}
//遍历单链表,并打印每个节点的值
void traverseList(ListNode* head) {
printf("合并后单链表:");
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}
int main() {
ListNode *list1 = createList();
ListNode *list2 = createList();
ListNode *mergedList = mergeLists(list1, list2);
traverseList(mergedList);
return 0;
}
各个函数的实现流程:
1. createList
用于创建一个单链表,返回头节点的指针。先读入要创建的链表长度,然后依次读入每个节点的值,创建新节点,并将其插入到链表尾部。需要注意的是,在第一次插入节点时,需要将头节点指针指向该节点。
2. mergeLists
用于合并两个有序的单链表,返回合并后的链表头节点的指针。如果其中一个链表为空,则直接返回另一个链表头节点的指针。为了简化代码逻辑,该函数先创建一个哨兵节点,指向新链表的头节点。然后依次比较两个链表的节点值,将较小的节点插入到新链表尾部。最后将剩余节点直接接到新链表尾部。
3. traverseList
用于遍历单链表,并打印每个节点的值。只需从头节点开始依次遍历每个节点,输出其数据域的值即可。
2、创建以单链表存放的两个多项式(为便于测试,每项的系数和指数可放在结点的结构体中),求二者之和,结果存放在第三个链表中。
#include <stdio.h>
#include <stdlib.h>
// 定义单链表结构体
typedef struct ListNode {
int coef;
int expn;
struct ListNode *next;
} ListNode;
//创建一个单链表,返回头节点的指针
ListNode* createList() {
ListNode *head = NULL, *p = NULL, *q = NULL;
int n = 0, coef = 0, expn = 0;
printf("请输入单链表的长度:");
scanf("%d", &n);
// 依次读入每个元素,创建新的节点,并插入链表尾部
for (int i = 1; i <= n; ++i) {
printf("请输入第%d个节点的系数和指数,中间以空格分隔:", i);
scanf("%d %d", &coef, &expn);
// 创建新节点
p = (ListNode*) malloc(sizeof(ListNode));
p->coef = coef;
p->expn = expn;
p->next = NULL;
// 插入链表尾部
if (head == NULL) {
head = p;
} else {
q = head;
while (q->next != NULL) {
q = q->next;
}
q->next = p;
}
}
return head;
}
//遍历单链表,并打印每个节点的值
void traverseList(ListNode* head) {
printf("遍历单链表:");
while (head != NULL) {
printf("%dx^%d+ ", head->coef, head->expn);
head = head->next;
}
printf("\n");
}
//实现两个多项式的加法,返回新链表头节点的指针
ListNode* addPolynomials(ListNode* poly1, ListNode* poly2) {
ListNode sentinel = {0, 0, NULL};
ListNode *tail = &sentinel;
while (poly1 != NULL && poly2 != NULL) {
if (poly1->expn < poly2->expn) {
// 创建新节点,并插入尾部
ListNode *p = (ListNode*) malloc(sizeof(ListNode));
p->coef = poly1->coef;
p->expn = poly1->expn;
p->next = NULL;
tail->next = p;
tail = tail->next;
poly1 = poly1->next;
} else if (poly1->expn > poly2->expn) {
// 创建新节点,并插入尾部
ListNode *p = (ListNode*) malloc(sizeof(ListNode));
p->coef = poly2->coef;
p->expn = poly2->expn;
p->next = NULL;
tail->next = p;
tail = tail->next;
poly2 = poly2->next;
} else {
int sum = poly1->coef + poly2->coef;
if (sum != 0) {
// 创建新节点,并插入尾部
ListNode *p = (ListNode*) malloc(sizeof(ListNode));
p->coef = sum;
p->expn = poly1->expn;
p->next = NULL;
tail->next = p;
tail = tail->next;
}
poly1 = poly1->next;
poly2 = poly2->next;
}
}
// 插入未处理完的节点
if (poly1 != NULL) {
tail->next = poly1;
}
if (poly2 != NULL) {
tail->next = poly2;
}
// 删除哨兵节点,返回新链表头节点
ListNode *result = sentinel.next;
free(&sentinel);
return result;
}
int main() {
ListNode *poly1 = createList();
ListNode *poly2 = createList();
traverseList(poly1);
traverseList(poly2);
ListNode *result = addPolynomials(poly1, poly2);
traverseList(result);
return 0;
}
每个函数的实现流程:
1. `createList()`: 创建一个单链表,并返回头节点的指针。
- 首先通过用户输入获取需要创建的单链表的长度。
- 然后使用循环逐个读入每个节点的系数和指数。
- 每次读入一个节点时,创建新的节点并赋值,然后插入到链表尾部。
- 循环结束后返回头节点的指针。
2. `traverseList(ListNode* head)`: 遍历链表,并打印每个节点的系数和指数。
- 通过循环遍历链表中的每个节点。
- 对于每个节点,打印其系数和指数。
- 循环结束后输出换行符。
3. `addPolynomials(ListNode* poly1, ListNode* poly2)`: 实现两个多项式的加法,并返回新链表的头节点指针。
- 创建一个哨兵节点 sentinel 作为新链表的头节点前面的辅助节点。
- 使用一个指针 tail 指向新链表的尾部节点,初始化为哨兵节点。
- 使用循环遍历 poly1 和 poly2 两个链表,比较当前节点的指数大小进行处理。
- 如果 poly1 的指数小于 poly2 的指数,将 poly1 的节点添加到新链表中,并更新 tail 指针和 poly1 指针。
- 如果 poly1 的指数大于 poly2 的指数,将 poly2 的节点添加到新链表中,并更新 tail 指针和 poly2 指针。
- 如果 poly1 和 poly2 的指数相等,计算两个系数的和 sum,如果 sum 不为 0,则创建新节点并添加到新链表中,并更新 tail 指针。
- 循环结束后,将未处理完的节点添加到新链表的尾部。
- 最后,删除哨兵节点,返回新链表的头节点指针。