链表,它由一系列节点(结构体) 组成,每个节点包含数据字段和指针 ,节点和节点之间通过指针连接在一起。与数组不同,链表中的元素在内存中不是连续存储的,而是通过指针连接在一起。
cpp
// 单向链表节点定义
struct Node {
int data; // 数据字段
struct Node* next; // 指向下一个节点的指针
};
单向链表
cpp
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构
struct Node {
int data;
struct Node* next;
};
// 创建新节点的函数
struct Node* createNode(int data) {
// 分配内存
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// 检查内存分配是否成功
if (newNode == NULL) {
printf("内存分配失败!\n");
exit(1);
}
// 初始化节点数据
newNode->data = data;
newNode->next = NULL;
return newNode;
}
在链表头部插入节点
cpp
// 在链表头部插入节点
struct Node* insertAtBeginning(struct Node* head, int data) {
// 创建新节点
struct Node* newNode = createNode(data);
// 将新节点的next指向当前的头节点
newNode->next = head;
// 更新头节点为新节点
return newNode;
}
在链表尾部插入节点
cpp
// 在链表尾部插入节点
struct Node* insertAtEnd(struct Node* head, int data) {
// 创建新节点
struct Node* newNode = createNode(data);
// 如果链表为空,新节点就是头节点
if (head == NULL) {
return newNode;
}
// 找到链表的最后一个节点
struct Node* current = head;
while (current->next != NULL) {
current = current->next;
}
// 将最后一个节点的next指向新节点
current->next = newNode;
// 返回头节点
return head;
}
在指定位置插入节点
cpp
// 在指定位置插入节点
struct Node* insertAtPosition(struct Node* head, int data, int position) {
// 如果位置是1,相当于在头部插入
if (position == 1) {
return insertAtBeginning(head, data);
}
// 创建新节点
struct Node* newNode = createNode(data);
// 找到要插入位置的前一个节点
struct Node* current = head;
for (int i = 1; i < position - 1 && current != NULL; i++) {
current = current->next;
}
// 检查位置是否有效
if (current == NULL) {
printf("位置无效!\n");
free(newNode);
return head;
}
// 插入新节点
newNode->next = current->next;
current->next = newNode;
return head;
}
删除节点
cpp
// 删除指定值的第一个节点
struct Node* deleteNode(struct Node* head, int key) {
// 如果链表为空,直接返回
if (head == NULL) {
return NULL;
}
// 如果头节点就是要删除的节点
if (head->data == key) {
struct Node* temp = head;
head = head->next;
free(temp);
return head;
}
// 查找要删除的节点
struct Node* current = head;
while (current->next != NULL && current->next->data != key) {
current = current->next;
}
// 如果找到了要删除的节点
if (current->next != NULL) {
struct Node* temp = current->next;
current->next = temp->next;
free(temp);
}
return head;
}
查找节点
cpp
// 查找指定值的节点
struct Node* searchNode(struct Node* head, int key) {
struct Node* current = head;
// 遍历链表
while (current != NULL) {
if (current->data == key) {
return current; // 找到节点,返回指针
}
current = current->next;
}
return NULL; // 未找到节点
}
打印链表
cpp
// 打印链表的所有节点
void printList(struct Node* head) {
struct Node* current = head;
printf("链表内容: ");
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
释放链表
cpp
// 释放链表的所有节点
void freeList(struct Node* head) {
struct Node* current = head;
struct Node* next;
while (current != NULL) {
next = current->next; // 保存下一个节点
free(current); // 释放当前节点
current = next; // 移动到下一个节点
}
}
cpp
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构
struct Node {
int data;
struct Node* next;
};
// 创建新节点
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("内存分配失败!\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 在链表头部插入节点
struct Node* insertAtBeginning(struct Node* head, int data) {
struct Node* newNode = createNode(data);
newNode->next = head;
return newNode;
}
// 在链表尾部插入节点
struct Node* insertAtEnd(struct Node* head, int data) {
struct Node* newNode = createNode(data);
if (head == NULL) {
return newNode;
}
struct Node* current = head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
return head;
}
// 在指定位置插入节点
struct Node* insertAtPosition(struct Node* head, int data, int position) {
if (position == 1) {
return insertAtBeginning(head, data);
}
struct Node* newNode = createNode(data);
struct Node* current = head;
for (int i = 1; i < position - 1 && current != NULL; i++) {
current = current->next;
}
if (current == NULL) {
printf("位置无效!\n");
free(newNode);
return head;
}
newNode->next = current->next;
current->next = newNode;
return head;
}
// 删除指定值的第一个节点
struct Node* deleteNode(struct Node* head, int key) {
if (head == NULL) {
return NULL;
}
if (head->data == key) {
struct Node* temp = head;
head = head->next;
free(temp);
return head;
}
struct Node* current = head;
while (current->next != NULL && current->next->data != key) {
current = current->next;
}
if (current->next != NULL) {
struct Node* temp = current->next;
current->next = temp->next;
free(temp);
}
return head;
}
// 查找指定值的节点
struct Node* searchNode(struct Node* head, int key) {
struct Node* current = head;
while (current != NULL) {
if (current->data == key) {
return current;
}
current = current->next;
}
return NULL;
}
// 打印链表
void printList(struct Node* head) {
struct Node* current = head;
printf("链表内容: ");
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
// 释放链表
void freeList(struct Node* head) {
struct Node* current = head;
struct Node* next;
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
}
// 获取链表长度
int getLength(struct Node* head) {
int count = 0;
struct Node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}
// 反转链表
struct Node* reverseList(struct Node* head) {
struct Node* prev = NULL;
struct Node* current = head;
struct Node* next = NULL;
while (current != NULL) {
next = current->next; // 保存下一个节点
current->next = prev; // 反转当前节点的指针
prev = current; // 移动prev指针
current = next; // 移动current指针
}
return prev; // 新的头节点
}
int main() {
struct Node* head = NULL;
// 在链表尾部插入节点
head = insertAtEnd(head, 10);
head = insertAtEnd(head, 20);
head = insertAtEnd(head, 30);
printf("初始链表:\n");
printList(head);
// 在链表头部插入节点
head = insertAtBeginning(head, 5);
printf("\n在头部插入5后:\n");
printList(head);
// 在指定位置插入节点
head = insertAtPosition(head, 15, 3);
printf("\n在位置3插入15后:\n");
printList(head);
// 删除节点
head = deleteNode(head, 20);
printf("\n删除值为20的节点后:\n");
printList(head);
// 查找节点
struct Node* found = searchNode(head, 15);
if (found != NULL) {
printf("\n找到值为15的节点\n");
} else {
printf("\n未找到值为15的节点\n");
}
// 获取链表长度
printf("\n链表长度: %d\n", getLength(head));
// 反转链表
head = reverseList(head);
printf("\n反转链表后:\n");
printList(head);
// 释放链表
freeList(head);
return 0;
}