想了想上一篇笔记中利用头节点作为返回值的代码虽然好理解,但是不是很正规.....所以又发了一篇关于以链表作为返回值的函数代码。
(详细的命名规则与具体函数逻辑见C语言实现链表篇)
一、主要函数实现:
void Compose_LinkList(LinkedList* list1, LinkedList* list2, LinkedList* list3)
{
ListNode* current1 = list1->head; // 定义迭代器1指向list1的头结点
ListNode* current2 = list2->head; // 定义迭代器2指向list2的头结点
while (current1 != NULL && current2 != NULL) //当cur1与cur2都不为空时
{
if (current1->data < current2->data) //表明此时需要插入List1的值进入List3
{
// 如果list1的当前节点值小于list2的,插入list1的当前节点到list3
Insert_LinkList(list3, list3->len, current1->data);
current1 = current1->next; // 移动list1的指针
}
else
{
// 否则,插入list2的当前节点到list3
Insert_LinkList(list3, list3->len, current2->data);
current2 = current2->next; // 移动list2的指针
}
}
//运行到这,表明有一个链表的迭代器已经为空了,而剩下的那个链表默认是有序的,所以无脑插入就可
// 处理剩余的节点
while (current1 != NULL)
{
Insert_LinkList(list3, list3->len, current1->data);
current1 = current1->next;
}
while (current2 != NULL)
{
Insert_LinkList(list3, list3->len, current2->data);
current2 = current2->next;
}
list3->len = list1->len + list2->len;
}
二、完整代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
typedef struct ListNode { //创建链表单独结点
int data; //数值域
struct ListNode* next; //下一个结点的指针域
}ListNode;
typedef struct LinkedList { //完整的链表
struct ListNode* head; //头结点,也就是一个单独结点
int len; //长度
}LinkedList;
void Creat_LinkedList(LinkedList* list) //创建一个链表
{
//把头节点置空,长度置为0
list->head = NULL;
list->len = 0;
}
void Destroy_LinkList(LinkedList* list) //销毁一个链表
{
while (list->head) //当头节点不为空时
{
ListNode* temp = list->head; //用一个临时的结点指向此时的头节点
list->head = list->head->next; //将指针指向头指针的下一个结点
free(temp); //把临时变量释放,也就把此时的结点释放
}
list->len = 0; //链表长度归0
}
//在链表中插入一个元素,在第i个位置插入value值
void Insert_LinkList(LinkedList* list, int i, int value)
{
if (i<0 || i>list->len) //位置越界
{
printf("插入失败");
return;
}
//表明位置合法:1.创建结点->改变指针方向
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));
newNode->data = value;//把数据赋值给新创建的数值域
if (i == 0) //表明需要在头头节点的位置插入元素(即改变头指针的指向),使用头插法
{
newNode->next = list->head; //新生成的结点,指向链表头
list->head = newNode; //改变链表头作为新生成的结点。
}
else //从链表头开始,执行n-1次循环
{
ListNode* current = list->head; //定义一个迭代器寻找结点
for (int j = 0; j < i - 1; j++)
{
current = current->next;//找到插入结点的前驱结点;
}
newNode->next = current->next;//把新结点的后记变成cur的后继结点
current->next = newNode;//把cur的后继变为新生成的结点。
}
list->len++;
}
//删除结点
void Delete_LinkList(LinkedList* list, int i)
{
if (i < 0 || i >= list->len)
{
printf("删除失败");
return;
}
if (i == 0) //删除链表的头节点
{
ListNode* temp = list->head->next;//把链表的头节点的后续结点进行一个缓存
free(list->head); //释放要删除的结点
list->head = temp; //把头节点指向第下一个结点
}
else //表示删除的不是头节点
{
ListNode* current = list->head; //定义一个迭代器
for (int j = 0; j < i - 1; j++)//找到需要删除节点的前驱节点
{
current = current->next;
}
ListNode* temp = current->next->next;//把要删除的后继节点存储起来
free(current->next);//利用free把要删除的节点给释放掉
current->next = temp;
}
list->len--;//长度减1
}
//通过元素来查找链表结点
ListNode* Find_element_Linked(LinkedList* list, int value)
{
ListNode* current = list->head;//先定义一个迭代器指向头节点
while (current) //当迭代器不为空时,也就是还没有遍历完整个链表
{
if (current->data == value) //找到了目标结点
{
return current;
}
current = current->next;//往下找;
}
return NULL;//表示没有找到
}
//通过下标来寻找链表的结点
ListNode* Find_Index_Linked(LinkedList* list, int i)
{
if (i < 0 || i >= list->len) //越界
{
printf("寻找错误");
return NULL;
}
ListNode* current = list->head;//迭代器
for (int j = 0; j < i; j++) //循环遍历寻找元素
{
current = current->next;//往后移
}
return current;
}
//更新链表的元素
void Update_LInked(LinkedList* list, int i, int value)
{
ListNode* temp = Find_Index_Linked(list, i);//直接调用通过下标来寻找链表节点的函数
if (temp) //如果节点存在
{
temp->data = value;//修改值即可
}
}
void Print_Linked(LinkedList* list)
{
ListNode* current = list->head;//迭代器
while (current)
{
printf("%d ->", current->data);
current = current->next; //往下走
}
printf("NULL\n");
}
void Compose_LinkList(LinkedList* list1, LinkedList* list2, LinkedList* list3)
{
ListNode* current1 = list1->head; // 定义迭代器1指向list1的头结点
ListNode* current2 = list2->head; // 定义迭代器2指向list2的头结点
while (current1 != NULL && current2 != NULL) //当cur1与cur2都不为空时
{
if (current1->data < current2->data) //表明此时需要插入List1的值进入List3
{
// 如果list1的当前节点值小于list2的,插入list1的当前节点到list3
Insert_LinkList(list3, list3->len, current1->data);
current1 = current1->next; // 移动list1的指针
}
else
{
// 否则,插入list2的当前节点到list3
Insert_LinkList(list3, list3->len, current2->data);
current2 = current2->next; // 移动list2的指针
}
}
//运行到这,表明有一个链表的迭代器已经为空了,而剩下的那个链表默认是有序的,所以无脑插入就可
// 处理剩余的节点
while (current1 != NULL)
{
Insert_LinkList(list3, list3->len, current1->data);
current1 = current1->next;
}
while (current2 != NULL)
{
Insert_LinkList(list3, list3->len, current2->data);
current2 = current2->next;
}
list3->len = list1->len + list2->len;
}
int main()
{
LinkedList list1;//定义一个链表
LinkedList list2;
LinkedList list3;
Creat_LinkedList(&list1);//初始化链表List1
Insert_LinkList(&list1, 0, 10);//插入值
Insert_LinkList(&list1, 1, 20);
Insert_LinkList(&list1, 2, 30);
Insert_LinkList(&list1, 3, 40);
Creat_LinkedList(&list2);//初始化链表List2
Insert_LinkList(&list2, 0, 15);//插入值
Insert_LinkList(&list2, 1, 25);
Insert_LinkList(&list2, 2, 35);
Insert_LinkList(&list2, 3, 45);
Creat_LinkedList(&list3);//初始化链表List3
Compose_LinkList(&list1, &list2, &list3);
Print_Linked(&list3);
printf("%d", list3.len);
system("pause");
return 0;
}