程序内有写详细备注,请了解链表的结构后观看
初始化链表 |
void initLinkedList(LinkedList *list) |
返回链表的长度 |
size_t getLength(const LinkedList *list) |
在指定位置插入元素 |
void insertAt(LinkedList *list, size_t index, int element) |
在末尾插入元素 |
void insertEnd(LinkedList *list, int element) |
删除指定位置的元素并返回被删除的元素 |
int deleteAt(LinkedList *list, size_t index) |
删除末尾元素 |
int deleteEnd(LinkedList *list) |
获取指定位置的元素 |
int getElementAt(const LinkedList *list, size_t index) |
修改指定位置的元素 |
void modifyAt(LinkedList *list, size_t index, int newValue) |
释放链表内存 |
void destroyLinkedList(LinkedList *list) |
#include <stdio.h>
#include <stdlib.h>
// 链表节点结构
typedef struct Node
{
int data; // 节点存储的数据
struct Node *next; // 指向下一个节点的数据(结构体指针)嵌套自己指向自己
} Node;
// 头节点,链表结构
typedef struct
{
Node *head; // 指针变量,头节点指针指向首元节点(带数据的)
size_t size; // 头节点中的数据是链表中的节点个数
} LinkedList;
// 初始化链表
void initLinkedList(LinkedList *list)
{
list->head = NULL; // 初始化头节点为空,截断链表
list->size = 0; // 初始化节点个数为0
}
// 返回链表的长度
size_t getLength(LinkedList *list)
{
return list->size; // 返回链表的节点个数
}
// 在指定位置插入元素
void insertAt(LinkedList *list, size_t index, int element)
{
if (index < 0 || index > list->size)
{
printf("输入的index数据非法\n");
return;
}
// 插入数据的过程
// 1、将数据封装到Node结构体的变量中
Node *newNode = (Node *)malloc(sizeof(Node)); // 创建新节点
newNode->data = element;
if (index == 0)
{
newNode->next = list->head; // 现在由新节点指针指向带数据的首元节点
list->head = newNode; // 将结点newNode赋值给list的后继结点,让头节点指针指向新节点数据
}
else
{
Node *prevNode = list->head; // 创建指针变量,令prevNode指向首元节点
for (size_t i = 0; i < index - 1; i++) // 指针已经在首元节点若在1处插入不用循环,故减1
{
prevNode = prevNode->next; // 链式结构不断的指向下一个
}
newNode->next = prevNode->next; // 让新节点指针指向后节点数据
prevNode->next = newNode; // 让前节点指针指向新节点数据
}
list->size++; // 更新节点数
}
// 在末尾插入元素
void insertEnd(LinkedList *list, int element)
{
insertAt(list, list->size, element); // 在链表末尾插入元素
}
// 删除指定位置的元素并返回被删除的元素
int deleteAt(LinkedList *list, size_t index)
{
if (index >= list->size)
{
return -1; // 忽略无效的删除位置
}
int deletedElement;
if (index == 0)
{
Node *temp = list->head; // 定义指针变量令temp指向首元节点(第一个带数据的节点)
list->head = temp->next; // 令头节点指向下一个节点跳过首元节点
deletedElement = temp->data; // 赋值
free(temp); // 释放被删除节点的内存
}
else
{
Node *prevNode = list->head; // 定义指针变量令prevNode指向首元节点
for (size_t i = 0; i < index - 1; i++)
{
prevNode = prevNode->next; // 遍历到位置
}
Node *temp = prevNode->next; // 定义指针变量令temp指向下个数据节点
prevNode->next = temp->next; // 跳过节点
deletedElement = temp->data; // 存储
free(temp); // 释放被删除节点的内存
}
list->size--;
return deletedElement;
}
// 获取指定位置的元素
int getElementAt(const LinkedList *list, size_t index)
{
if (index >= list->size)
{
return -1; // 返回无效的索引
}
Node *currentNode = list->head; // 指向首元节点
for (size_t i = 0; i < index; i++) // 插入、删除index需要减一
{
currentNode = currentNode->next; // 遍历找到位置,当index=1时需要运行一次刚好到
}
return currentNode->data; // 返回指定位置的元素
}
// 修改指定位置的元素
void modifyAt(LinkedList *list, size_t index, int newValue)
{
if (index >= list->size)
{
return; // 忽略无效的修改位置
}
Node *currentNode = list->head; // 指向首元节点
for (size_t i = 0; i < index; i++)
{
currentNode = currentNode->next; // 遍历找到位置,当index=1时需要运行一次刚好到
}
currentNode->data = newValue; // 修改节点的值
}
// 释放链表内存
void destroyLinkedList(LinkedList *list)
{
Node *currentNode = list->head; // 指向首元节点
while (currentNode != NULL) // 最后的节点为空
{
Node *temp = currentNode; // currentNode的值给temp,相当与中间节点释放它链表不受影响
currentNode = currentNode->next; // 令下一个节点数值赋值给currentNode
free(temp); // 释放temp节点的内存,一个一个释放直到结束
}
list->head = NULL; // 头节点置为空
list->size = 0; // 节点个数置为0
}
int main()
{
LinkedList myList; // 声明链表
initLinkedList(&myList);
printf("初始化链表成功!\n");
insertEnd(&myList, 1); // 链表尾部插入元素1
insertEnd(&myList, 2); // 链表尾部插入元素2
printf("向链表插入了2个元素\n");
printf("链表长度为 %zu\n", getLength(&myList)); // 获取链表长度
insertAt(&myList, 1, 3); // 在索引1处插入元素3
printf("在索引1处插入元素3\n");
printf("链表长度为:%zu\n", getLength(&myList)); // 再次获取链表长度
printf("索引1处的元素为:%d\n", getElementAt(&myList, 1)); // 获取索引1处的元素
modifyAt(&myList, 0, 4); // 修改索引0处的元素
printf("把索引0处的元素修改为4\n");
printf("索引0处的元素为:%d\n", getElementAt(&myList, 0)); // 获取索引0处的元素
printf("删除索引1处的元素,该元素是:%d\n", deleteAt(&myList, 1)); // 删除索引1处的元素
destroyLinkedList(&myList); // 销毁链表
printf("链表销毁成功!\n");
printf("链表长度为:%zu\n", getLength(&myList)); // 再次获取链表长度
getchar();
return 0;
}