在C语言中,链表是一种常见的数据结构,它通过节点(Node)的集合来表示序列,其中每个节点都包含数据部分和指向下一个节点的指针(或链接)。链表操作主要包括创建链表、插入节点、删除节点、查找节点、遍历链表等。使用链表可以实现栈或队列、哈希表、图等其他复杂数据结构。
创建链表
创建链表通常需要先定义节点结构体、随后初始化头指针并逐个创建并链接节点,节点结构体通常包含至少两个成员:一个是存储数据的数据域,另一个是存储指向下一个节点指针的指针域。
定义表示链表中的节点结构体的方法如下:
typedef struct Node {
int data; // 节点存储的数据
struct Node* next; // 指向下一个节点的指针
} Node;
创建空链表并返回链表的头指针的方法函数如下:
Node* createList() {
Node* head = NULL; // 初始化头指针为NULL,表示创建一个空链表
return head; // 返回头指针
}
插入节点
在链表中插入节点通常涉及到找到插入位置的前一个节点,然后改变指针的指向以包含新节点。插入操作可以分为头插法、尾插法和在指定位置插入。
头插法:新节点插入到链表头部。
void AtHead(Node** head, int newData) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = newData;
newNode->next = *head;
*head = newNode;
}
尾插法:新节点插入到链表尾部,需要维护一个尾指针来简化操作。
void insertAtTail(Node** head, int newData) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = newData;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode;
return;
}
Node* last = *head;
while (last->next != NULL) {
last = last->next;
}
last->next = newNode;
}
在指定位置插入:找到指定位置的前一个节点,然后插入新节点。
void insertAtPosition(Node** head, int newData, int position) {
if (position == 0) {
insertAtHead(head, newData);
return;
}
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = newData;
newNode->next = NULL;
if (*head == NULL) {
*head = newNode;
return;
}
Node* temp = *head;
for (int i = 0; temp != NULL && i < position - 1; i++) {
temp = temp->next;
}
if (temp == NULL) {
free(newNode); // 位置无效的话就释放新节点并返回
return;
}
newNode->next = temp->next;
temp->next = newNode;
}
删除节点
删除链表中的节点通常涉及到找到要删除的节点的前一个节点,然后改变其指针域以跳过要删除的节点,如果删除的是头节点,则需要特别处理,因为头指针本身可能需要改变。
void deleteNode(Node** head, int key) {
Node* temp = *head, *prev = NULL;
if (temp != NULL && temp->data == key) {
*head = temp->next; // 头节点就是要删除的节点,比如删除key节点
free(temp);
return;
}
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) return; // 没有找到要删除的节点
prev->next = temp->next;
free(temp);
}
查找节点及遍历链表
查找链表中的节点通常涉及遍历链表,比较每个节点的数据域直到找到所需的节点或遍历完整个链表。查找操作可以返回节点的指针或节点的位置。
Node* findNode(Node* head, int value) {
Node* temp = head;
while (temp != NULL) {
if (temp->data == value) {
return temp; // 找到节点并返回节点的指针
}
temp = temp->next; // 继续遍历链表
}
return NULL; // 没有找到节点就返回NULL
}
综合示例
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构体
typedef struct Node {
int data;
struct Node* next;
} Node;
// 创建新节点
Node* createNode(int data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 头插法
void insertAtHead(Node** head, int data) {
Node* newNode = createNode(data);
newNode->next = *head;
*head = newNode;
}
// 尾插法
void insertAtTail(Node** head, int data) {
Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
return;
}
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
// 删除链表中第一个数据域为指定值的节点的函数
void deleteNode(Node** head, int data) {
Node* temp = *head;
Node* prev = NULL;
while (temp != NULL && temp->data != data) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
return;
}
if (prev == NULL) {
*head = temp->next;
} else {
prev->next = temp->next;
}
free(temp);
}
// 返回链表中第一个数据域为指定值的节点的指针的函数
Node* findNode(Node* head, int data) {
Node* temp = head;
while (temp != NULL) {
if (temp->data == data) {
return temp;
}
temp = temp->next;
}
return NULL;
}
// 打印链表的函数
void printList(Node* head) {
Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 释放链表内存的函数
void freeList(Node* head) {
Node* temp;
while (head != NULL) {
temp = head;
head = head->next;
free(temp);
}
}
int main() {
Node* head = NULL;
// 插入节点
insertAtHead(&head, 3);
insertAtHead(&head, 2);
insertAtHead(&head, 1);
insertAtTail(&head, 4);
printList(head); // 调用函数打印链表
// 删除节点
deleteNode(&head, 3);
printList(head);
// 查找节点
Node* foundNode = findNode(head, 2);
if (foundNode != NULL) {
printf("Found node with data: %d\n", foundNode->data);
} else {
printf("Node with data 2 not found.\n");
}
// 释放链表内存
freeList(head);
return 0;
}
代码输出:
1 -> 2 -> 3 -> 4 -> NULL
1 -> 2 -> 4 -> NULL
Found node with data: 2