#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构
typedef struct Node {
int data;
struct Node* next;
} Node;
// 动态分配新节点内存
Node* createNode(int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
fprintf(stderr, "内存分配失败\n");
return NULL;
}
newNode->data = value;
newNode->next = NULL;
return newNode;
}
// 在链表头部插入新节点
void insertAtHead(Node** head, int value) {
Node* newNode = createNode(value);
if (newNode != NULL) {
newNode->next = *head;
*head = newNode;
}
}
// 删除指定节点
void deleteNode(Node** head, int value) {
Node* current = *head;
Node* prev = NULL;
// 找到要删除的节点
while (current != NULL && current->data != value) {
prev = current;
current = current->next;
}
if (current == NULL) {
printf("未找到值为 %d 的节点\n", value);
return;
}
// 如果要删除的是头节点
if (prev == NULL) {
*head = current->next;
} else {
prev->next = current->next;
}
free(current);
}
// 释放整个链表内存
void freeList(Node** head) {
Node* current = *head;
Node* nextNode;
while (current != NULL) {
nextNode = current->next;
free(current);
current = nextNode;
}
*head = NULL;
}
// 打印链表
void printList(Node* head) {
Node* current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
int main() {
Node* head = NULL;
insertAtHead(&head, 1);
insertAtHead(&head, 2);
insertAtHead(&head, 3);
printf("链表: ");
printList(head);
deleteNode(&head, 2);
printf("删除节点 2 后链表: ");
printList(head);
freeList(&head);
printf("释放链表后,链表已为空\n");
return 0;
}
指针内存管理说明
- 动态内存分配:
- 使用
malloc
函数为新节点分配内存。如果分配成功,返回指向新分配内存的指针;如果失败,返回 NULL
。例如在 createNode
函数中:Node* newNode = (Node*)malloc(sizeof(Node));
。
- 插入新节点:
- 在
insertAtHead
函数中,先创建新节点,然后调整指针。newNode->next = *head;
将新节点的 next
指针指向当前头节点,*head = newNode;
再将头指针更新为新节点,从而完成新节点的插入,确保内存的正确连接。
- 删除指定节点:
- 在
deleteNode
函数中,通过遍历链表找到要删除的节点。在删除节点时,调整前一个节点的 next
指针跳过要删除的节点(prev->next = current->next;
),然后使用 free
函数释放要删除节点的内存(free(current);
),避免内存泄漏。如果要删除的是头节点,直接更新头指针(*head = current->next;
)。
- 释放整个链表内存:
- 在
freeList
函数中,使用一个临时指针 nextNode
保存当前节点的下一个节点位置,然后释放当前节点的内存(free(current);
),再将当前节点移动到下一个节点(current = nextNode;
),如此循环直到链表末尾,确保链表中的所有节点内存都被释放,避免内存泄漏。最后将头指针置为 NULL
(*head = NULL;
)。