C语言链表数据结构的设计与代码实现
1. 概述
本文使用C语言实践了一个简单的单向链表数据结构。该链表支持基本的链表操作,包括创建、插入、删除、查找和遍历等功能。
2. 数据结构定义
2.1 节点结构 (Node)
typedef struct Node {
int data; // 节点数据
struct Node* next; // 指向下一个节点的指针
} Node;
2.2 链表结构 (LinkedList)
typedef struct LinkedList {
Node* head; // 链表头指针
} LinkedList;
3. 链表操作
3.1 创建链表
LinkedList* createList() {
LinkedList* list = (LinkedList*)malloc(sizeof(LinkedList));
list->head = NULL; // 初始化头指针为空
return list;
}
3.2 插入节点
void insertAtHead(LinkedList* list, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = list->head;
list->head = newNode;
}
3.3 删除节点
int deleteNode(LinkedList* list, int data) {
Node* current = list->head;
Node* prev = NULL;
while (current != NULL) {
if (current->data == data) {
if (prev == NULL) {
list->head = current->next;
} else {
prev->next = current->next;
}
free(current);
return 1;
}
prev = current;
current = current->next;
}
return 0;
}
3.4 查找节点
Node* findNode(LinkedList* list, int data) {
Node* current = list->head;
while (current != NULL) {
if (current->data == data) {
return current;
}
current = current->next;
}
return NULL;
}
3.5 遍历链表
void traverseList(LinkedList* list) {
Node* current = list->head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
3.6 释放链表
void freeList(LinkedList* list) {
Node* current = list->head;
Node* next;
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
}
4. 使用示例
int main() {
LinkedList* list = createList();
insertAtHead(list, 10);
insertAtHead(list, 20);
insertAtHead(list, 30);
traverseList(list);
deleteNode(list, 20);
traverseList(list);
freeList(list);
return 0;
}
5. 注意事项
- 在插入和删除节点时,需要确保链表头指针不为空。
- 在释放链表时,需要确保链表头指针为空。
- 在查找节点时,需要确保链表头指针不为空。
- 在遍历链表时,需要确保链表头指针不为空。
5. 完整代码
#include <stdio.h>
#include <stdlib.h>
// 链表节点结构
typedef struct Node {
int data; // 节点数据
struct Node* next; // 指向下一个节点的指针
} Node;
// 链表结构
typedef struct LinkedList {
Node* head; // 链表头指针
} LinkedList;
/**
* @brief 创建一个新的链表
* @return 返回指向新链表的指针
*/
LinkedList* createList() {
LinkedList* list = (LinkedList*)malloc(sizeof(LinkedList));
list->head = NULL; // 初始化头指针为空
return list;
}
/**
* @brief 在链表的头部插入一个新节点
* @param list 链表指针
* @param data 要插入的数据
*/
void insertAtHead(LinkedList* list, int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = data; // 设置节点数据
newNode->next = list->head; // 新节点指向当前头节点
list->head = newNode; // 更新头指针
}
/**
* @brief 删除链表中指定值的节点
* @param list 链表指针
* @param data 要删除的节点数据
* @return 1 如果删除成功,0 如果未找到节点
*/
int deleteNode(LinkedList* list, int data) {
Node* current = list->head;
Node* previous = NULL;
while (current != NULL) {
if (current->data == data) {
if (previous == NULL) {
list->head = current->next; // 删除头节点
} else {
previous->next = current->next; // 删除中间或尾节点
}
free(current); // 释放节点内存
return 1; // 删除成功
}
previous = current;
current = current->next;
}
return 0; // 未找到节点
}
/**
* @brief 遍历链表并打印节点数据
* @param list 链表指针
*/
void traverseList(LinkedList* list) {
Node* current = list->head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n"); // 表示链表结束
}
/**
* @brief 释放链表的所有节点
* @param list 链表指针
*/
void freeList(LinkedList* list) {
Node* current = list->head;
Node* nextNode;
while (current != NULL) {
nextNode = current->next; // 保存下一个节点
free(current); // 释放当前节点
current = nextNode; // 移动到下一个节点
}
free(list); // 释放链表结构
}
使用示例:
/**
* @brief 链表使用示例
*/
int main() {
// 创建链表
LinkedList* list = createList();
printf("创建空链表\n");
traverseList(list);
// 插入节点
printf("\n在头部插入节点: 10, 20, 30\n");
insertAtHead(list, 10);
insertAtHead(list, 20);
insertAtHead(list, 30);
traverseList(list);
// 删除节点
printf("\n删除节点: 20\n");
deleteNode(list, 20);
traverseList(list);
// 查找节点
printf("\n查找节点: 10\n");
Node* found = findNode(list, 10);
if(found) {
printf("找到节点,数据为: %d\n", found->data);
} else {
printf("未找到节点\n");
}
// 释放链表
printf("\n释放链表\n");
freeList(list);
printf("链表已释放\n");
return 0;
}
输出:
创建空链表
NULL
在头部插入节点: 10, 20, 30
30 -> 20 -> 10 -> NULL
删除节点: 20
30 -> 10 -> NULL
查找节点: 10
找到节点,数据为: 10
释放链表
链表已释放