题目要求
将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的存储空间。表中不允许有重复的数据。
*核心代码实现如下:
//合并两个有序链表
bool MergeLinkedLists(List* list1, List* list2) {
int data1p;
int data1n;
int data2;
//定义临时指针存储当前结点指针,避免修改头结点
Node* tempNode1 = list1;
Node* tempNode2 = list2;
//移动指针跳过头结点
tempNode1 = tempNode1->next;
tempNode2 = tempNode2->next;
while (tempNode2 != NULL) {
data2 = tempNode2->data;
//遍历链表1将链表2有序插入其中
while (tempNode1 != NULL) {
data1p = tempNode1->data;
data1n = tempNode1->next->data;
if (data2 > data1p && data2 < data1n) {
//将链表2中符合此条件的结点插入到链表1两个结点之间
//修改链表2头结点的指向
if (tempNode2->next != NULL) {
list2->next = tempNode2->next;
}
else {
//此时链表2中的结点已全部插入完毕,链表2为空
list2->next = NULL;
}
//将插入的结点连接到当前链表1结点的后向指针的前面
tempNode2->next = tempNode1->next;
//将插入的结点连接到当前链表1结点之后
tempNode1->next = tempNode2;
break;
}//比第一个结点的值小,将其插入到链表1的头结点之后
else if (data2 < list1->next->data) {
//修改链表2头结点的指向
if (tempNode2->next != NULL) {
list2->next = tempNode2->next;
}
else {
//此时链表2中的结点已全部插入完毕,链表2为空
list2->next = NULL;
}
//将插入的结点连接到原来第一个结点的前面
tempNode2->next = list1->next;
//将插入的结点连接到头结点之后
list1->next = tempNode2;
break;
}
else {
//继续向后查找
//移动指针
tempNode1 = tempNode1->next;
continue;
}
}
//修改为链表2的当前结点
tempNode2 = list2->next;
}
}
完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
//(1)将两个递增的有序链表合并为一个递增的有序链表。
//要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的存储空间。表中不允许有重复的数据。
//结点
typedef struct LinkedNode {
int data;
struct LinkedNode* next;
}Node,List;
//初始化:带头结点
bool init(List* list) {
//为头结点分配内存
list = (Node*)malloc(sizeof(Node));
if (list == NULL) {
printf("头结点内存分配失败!初始化失败!\n");
return false;
}
list->next = NULL;
return true;
}
//创建第一个递增有序链表
bool createList1(List* list) {
//创建一个包含十个结点的链表
//链表中每个结点的值依次为:2,4,6,8,10,12,14,16,18,20
Node* node;
//定义临时指针存储当前结点指针,避免修改头结点
Node* tempNode = list;
for (int i = 1; i <= 10; i++)
{
//为新节点分配内存
node = (Node*)malloc(sizeof(Node));
if (node == NULL) {
printf("新结点内存分配失败!\n");
return false;
}
//为结点赋值
node->data = i * 2;
//将结点连接到链表后面
tempNode->next = node;
node->next = NULL;
//移动指针
tempNode = tempNode->next;
}
return true;
}
//创建第二个递增有序链表
bool createList2(List* list) {
//创建一个包含5个结点的链表
Node* node;
//定义临时指针存储当前结点指针,避免修改头结点
Node* tempNode = list;
int t = -1;
for (int i = 1; i <= 5; i++)
{
//为新节点分配内存
node = (Node*)malloc(sizeof(Node));
if (node == NULL) {
printf("新结点内存分配失败!\n");
return false;
}
//为结点赋值
t = t + 2;
node->data = t;
//将结点连接到链表后面
tempNode->next = node;
node->next = NULL;
//移动指针
tempNode = tempNode->next;
}
return true;
}
//打印链表
void printList(List* list) {
//定义临时指针存储当前结点指针,避免修改头结点
Node* tempNode = list;
//移动指针跳过头结点
tempNode = tempNode->next;
while (tempNode != NULL) {
printf("%d\n", tempNode->data);
//移动指针
tempNode = tempNode->next;
}
}
//合并两个有序链表
bool MergeLinkedLists(List* list1, List* list2) {
int data1p;
int data1n;
int data2;
//定义临时指针存储当前结点指针,避免修改头结点
Node* tempNode1 = list1;
Node* tempNode2 = list2;
//移动指针跳过头结点
tempNode1 = tempNode1->next;
tempNode2 = tempNode2->next;
while (tempNode2 != NULL) {
data2 = tempNode2->data;
//遍历链表1将链表2有序插入其中
while (tempNode1 != NULL) {
data1p = tempNode1->data;
data1n = tempNode1->next->data;
if (data2 > data1p && data2 < data1n) {
//将链表2中符合此条件的结点插入到链表1两个结点之间
//修改链表2头结点的指向
if (tempNode2->next != NULL) {
list2->next = tempNode2->next;
}
else {
//此时链表2中的结点已全部插入完毕,链表2为空
list2->next = NULL;
}
//将插入的结点连接到当前链表1结点的后向指针的前面
tempNode2->next = tempNode1->next;
//将插入的结点连接到当前链表1结点之后
tempNode1->next = tempNode2;
break;
}//比第一个结点的值小,将其插入到链表1的头结点之后
else if (data2 < list1->next->data) {
//修改链表2头结点的指向
if (tempNode2->next != NULL) {
list2->next = tempNode2->next;
}
else {
//此时链表2中的结点已全部插入完毕,链表2为空
list2->next = NULL;
}
//将插入的结点连接到原来第一个结点的前面
tempNode2->next = list1->next;
//将插入的结点连接到头结点之后
list1->next = tempNode2;
break;
}
else {
//继续向后查找
//移动指针
tempNode1 = tempNode1->next;
continue;
}
}
//修改为链表2的当前结点
tempNode2 = list2->next;
}
}
int main() {
List list1;
List list2;
//初始化链表
if (init(&list1) && init(&list2)) {
printf("链表初始化成功!\n");
}
else {
printf("链表初始化失败!\n");
return -1;
}
//创建链表
if (!createList1(&list1)) {
printf("链表1创建失败\n");
return -1;
}
if (!createList2(&list2)) {
printf("链表2创建失败\n");
return -1;
}
printList(&list1);
printf("----------------------------------\n");
printList(&list2);
printf("----------------------------------\n");
//合并两条链表
MergeLinkedLists(&list1, &list2);
printList(&list1);
return 0;
}