前言:请往下翻一翻,链表代码汇总(8种链表的实现代码),代码问题请评论区留言。
目录
链表的性质
性质
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素(这组存储单元可以是连续的,也可以是不连续的)。每个数据元素除了存储其本身的信息之外,还存储一个指示其直接后继的信息(基地址指针),所以数据元素有两个域:数据域和指针域。
注意:这只是普通链表的性质,其他变式链表可基于此基础上改进(就看你设计的算法哪种数据结构支持的更好了),例如双向链表指针域由两部分组成。
分类
头节点:
按链表是否带有头节点:带头链表和不带头链表
方向:
按链表访问方向: 单向链表和双向链表
循环:
按链表是否构成循环:循环链表和不循环链表
小结:
链表常规分类一共8种。
- 单向--不带头--不循环链表
- 单向--不带头--循环链表
- 单向--带头--不循环链表
- 单向--带头--循环链表
- 双向--不带头--不循环链表
- 双向--不带头--循环链表
- 双向--带头--不循环链表
- 双向向--带头--循环链表
常规操作是初始化、增、删、查、改、长度、清空释放等,具体要根据你的需求来具体设计。下面提供具体实现代码,仅供参考。
代码实现
1)单向--不带头--不循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* next;
} Node;
// 创建新节点
Node* createNode(data_t data) {
// 分配新节点的内存空间
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
// 设置新节点的数据和指针
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化链表
Node* initList() {
return NULL;
}
// 头插法
Node* insertAtHead(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 将新节点插入链表头部
newNode->next = head;
head = newNode;
return head;
}
// 尾插法
Node* insertAtTail(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 如果链表为空,将新节点作为链表的头节点
if (head == NULL) {
return newNode;
}
// 找到链表的尾部节点,将新节点插入尾部
Node* temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
return head;
}
// 指定位置插入
Node* insertAtPos(Node* head, data_t data, int pos) {
// 检查插入位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return head;
}
// 头部插入
if (pos == 0) {
return insertAtHead(head, data);
}
// 创建新节点
Node* newNode = createNode(data);
// 插入位置不为头部,遍历链表找到插入位置
Node* temp = head;
int count = 0;
while (count < pos - 1 && temp != NULL) {
temp = temp->next;
count++;
}
// 插入位置超出链表长度,位置无效
if (temp == NULL) {
printf("Invalid position.\n");
return head;
}
// 插入新节点
newNode->next = temp->next;
temp->next = newNode;
return head;
}
// 头删法
Node* deleteAtHead(Node* head) {
// 检查链表是否为空
if (head == NULL) {
printf("The list is empty.\n");
return head;
}
// 删除头节点
Node* temp = head;
head = head->next;
free(temp);
return head;
}
// 尾删法
Node* deleteAtTail(Node* head) {
// 检查链表是否为空
if (head == NULL) {
printf("The list is empty.\n");
return head;
}
// 链表只有一个节点时,直接删除头节点
if (head->next == NULL) {
return deleteAtHead(head);
}
// 找到尾节点的前一个节点
Node* temp = head;
while (temp->next->next != NULL) {
temp = temp->next;
}
// 删除尾节点
Node* tail = temp->next;
temp->next = NULL;
free(tail);
return head;
}
// 指定位置删除
Node* deleteAtPos(Node* head, int pos) {
// 检查删除位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return head;
}
// 头部删除
if (pos == 0) {
return deleteAtHead(head);
}
// 遍历链表找到删除位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos - 1 && temp != NULL) {
temp = temp->next;
count++;
}
// 删除位置超出链表长度,位置无效
if (temp == NULL || temp->next == NULL) {
printf("Invalid position.\n");
return head;
}
// 删除节点
Node* deletedNode = temp->next;
temp->next = deletedNode->next;
free(deletedNode);
return head;
}
// 查找节点
Node* selectNode(Node* head, int pos) {
// 检查查找位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return NULL;
}
// 遍历链表找到查找位置的节点
Node* temp = head;
int count = 0;
while (count < pos && temp != NULL) {
temp = temp->next;
count++;
}
// 查找位置超出链表长度,位置无效
if (temp == NULL) {
printf("Invalid position.\n");
return NULL;
}
return temp;
}
// 更新节点
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表
void displayList(Node* head) {
Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 清空链表
void clearList(Node** head) {
Node* temp = *head;
Node* nextNode;
while (temp != NULL) {
nextNode = temp->next;
free(temp);
temp = nextNode;
}
*head = NULL;
}
// 释放模块
void destroyList(Node** head) {
clearList(head);
}
int main() {
Node* head = initList();
// 测试插入操作
head = insertAtHead(head, 3);
head = insertAtTail(head, 5);
head = insertAtPos(head, 7, 1);
displayList(head);
// 测试删除操作
head = deleteAtHead(head);
head = deleteAtTail(head);
head = deleteAtPos(head, 0);
displayList(head);
// 测试查找和更新操作
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found Node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated Node data: %d\n", node->data);
}
else {
printf("Node not found!\n");
}
// 清空链表
clearList(&head);
displayList(head);
// 释放链表内存
destroyList(&head);
if (head == NULL) {
printf("List destroyed.\n");
}
return 0;
}
2)单向--不带头--循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* next;
} Node;
// 创建新节点
Node* createNode(data_t data) {
// 分配新节点的内存空间
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
// 设置新节点的数据和指针
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化链表
Node* initList() {
return NULL;
}
// 头插法
Node* insertAtHead(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 如果链表为空,将新节点作为链表的头节点
if (head == NULL) {
newNode->next = newNode;
return newNode;
}
// 找到链表的尾节点
Node* tail = head;
while (tail->next != head) {
tail = tail->next;
}
// 将新节点插入链表头部
newNode->next = head;
tail->next = newNode;
return newNode;
}
// 尾插法
Node* insertAtTail(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 如果链表为空,将新节点作为链表的头节点
if (head == NULL) {
newNode->next = newNode;
return newNode;
}
// 找到链表的尾节点
Node* tail = head;
while (tail->next != head) {
tail = tail->next;
}
// 将新节点插入链表尾部
tail->next = newNode;
newNode->next = head;
return head;
}
// 指定位置插入
Node* insertAtPos(Node* head, data_t data, int pos) {
// 检查插入位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return head;
}
// 头部插入
if (pos == 0) {
return insertAtHead(head, data);
}
// 创建新节点
Node* newNode = createNode(data);
// 插入位置不为头部,遍历链表找到插入位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos - 1 && temp->next != head) {
temp = temp->next;
count++;
}
// 插入位置超出链表长度,位置无效
if (temp->next == head && count < pos - 1) {
printf("Invalid position.\n");
return head;
}
// 插入新节点
newNode->next = temp->next;
temp->next = newNode;
return head;
}
// 头删法
Node* deleteAtHead(Node* head) {
// 检查链表是否为空
if (head == NULL) {
printf("The list is empty.\n");
return head;
}
// 如果链表只有一个节点,删除后返回NULL
if (head->next == head) {
free(head);
return NULL;
}
// 找到链表的尾节点
Node* tail = head;
while (tail->next != head) {
tail = tail->next;
}
// 删除头节点
Node* temp = head;
head = head->next;
tail->next = head;
free(temp);
return head;
}
// 尾删法
Node* deleteAtTail(Node* head) {
// 检查链表是否为空
if (head == NULL) {
printf("The list is empty.\n");
return head;
}
// 如果链表只有一个节点,删除后返回NULL
if (head->next == head) {
free(head);
return NULL;
}
// 找到链表的尾节点和尾节点的前一个节点
Node* tail = head;
Node* prev = NULL;
while (tail->next != head) {
prev = tail;
tail = tail->next;
}
// 删除尾节点
prev->next = head;
free(tail);
return head;
}
// 指定位置删除
Node* deleteAtPos(Node* head, int pos) {
// 检查删除位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return head;
}
// 头部删除
if (pos == 0) {
return deleteAtHead(head);
}
// 遍历链表找到删除位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos - 1 && temp->next != head) {
temp = temp->next;
count++;
}
// 删除位置超出链表长度,位置无效
if (temp->next == head && count < pos - 1) {
printf("Invalid position.\n");
return head;
}
// 删除节点
Node* deletedNode = temp->next;
temp->next = deletedNode->next;
free(deletedNode);
return head;
}
// 查找节点
Node* selectNode(Node* head, int pos) {
// 检查查找位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return NULL;
}
// 遍历链表找到查找位置的节点
Node* temp = head;
int count = 0;
while (count < pos && temp->next != head) {
temp = temp->next;
count++;
}
// 查找位置超出链表长度,位置无效
if (temp->next == head && count < pos) {
printf("Invalid position.\n");
return NULL;
}
return temp;
}
// 更新节点
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表
void displayList(Node* head) {
if (head == NULL) {
printf("The list is empty.\n");
return;
}
Node* temp = head;
do {
printf("%d -> ", temp->data);
temp = temp->next;
} while (temp != head);
printf("HEAD\n");
}
// 清空链表
void clearList(Node** head) {
if (*head == NULL) {
return;
}
Node* temp = *head;
Node* nextNode = NULL;
do {
nextNode = temp->next;
free(temp);
temp = nextNode;
} while (temp != *head);
*head = NULL;
}
// 释放链表内存
void destroyList(Node** head) {
clearList(head);
}
int main() {
// 初始化链表
Node* head = initList();
// 插入操作
head = insertAtHead(head, 3);
head = insertAtTail(head, 5);
head = insertAtPos(head, 7, 1);
displayList(head);
// 删除操作
head = deleteAtHead(head);
head = deleteAtTail(head);
head = deleteAtPos(head, 0);
displayList(head);
head = insertAtHead(head, 3);
head = insertAtTail(head, 5);
// 查找和更新操作
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found Node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated Node data: %d\n", node->data);
}
else {
printf("Node not found!\n");
}
// 清空链表
clearList(&head);
displayList(head);
// 释放链表内存
destroyList(&head);
if (head == NULL) {
printf("List destroyed.\n");
}
return 0;
}
3)单向--带头--不循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* next;
} Node;
// 创建新节点
Node* createNode(data_t data) {
// 分配新节点的内存空间
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
// 设置新节点的数据和指针
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化链表
Node* initList() {
// 创建头节点,并将其数据域设为0
Node* head = createNode(0);
head->next = NULL;
return head;
}
// 头插法
void insertAtHead(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 将新节点插入链表头部
newNode->next = head->next;
head->next = newNode;
}
// 尾插法
void insertAtTail(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 找到链表的尾节点
Node* tail = head;
while (tail->next != NULL) {
tail = tail->next;
}
// 将新节点插入链表尾部
tail->next = newNode;
}
// 指定位置插入
void insertAtPos(Node* head, data_t data, int pos) {
// 检查插入位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return;
}
// 创建新节点
Node* newNode = createNode(data);
// 插入位置不为头部,遍历链表找到插入位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos && temp->next != NULL) {
temp = temp->next;
count++;
}
// 插入新节点
newNode->next = temp->next;
temp->next = newNode;
}
// 头删法
void deleteAtHead(Node* head) {
// 检查链表是否为空
if (head->next == NULL) {
printf("The list is empty.\n");
return;
}
// 删除头节点
Node* temp = head->next;
head->next = temp->next;
free(temp);
}
// 尾删法
void deleteAtTail(Node* head) {
// 检查链表是否为空
if (head->next == NULL) {
printf("The list is empty.\n");
return;
}
// 找到链表的尾节点和尾节点的前一个节点
Node* prev = head;
Node* tail = head->next;
while (tail->next != NULL) {
prev = tail;
tail = tail->next;
}
// 删除尾节点
prev->next = NULL;
free(tail);
}
// 指定位置删除
void deleteAtPos(Node* head, int pos) {
// 检查删除位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return;
}
// 遍历链表找到删除位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos && temp->next != NULL) {
temp = temp->next;
count++;
}
// 删除位置超出链表长度,位置无效
if (temp->next == NULL) {
printf("Invalid position.\n");
return;
}
// 删除节点
Node* deletedNode = temp->next;
temp->next = deletedNode->next;
free(deletedNode);
}
// 查找节点
Node* selectNode(Node* head, int pos) {
// 检查查找位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return NULL;
}
// 遍历链表找到查找位置的节点
Node* temp = head->next;
int count = 0;
while (count < pos && temp != NULL) {
temp = temp->next;
count++;
}
// 查找位置超出链表长度,位置无效
if (temp == NULL) {
printf("Invalid position.\n");
return NULL;
}
return temp;
}
// 更新节点
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表
void displayList(Node* head) {
Node* temp = head->next;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 清空链表
void clearList(Node* head) {
Node* temp = head->next;
while (temp != NULL) {
Node* nextNode = temp->next;
free(temp);
temp = nextNode;
}
head->next = NULL;
}
// 释放链表内存
void destroyList(Node* head) {
clearList(head);
free(head);
}
int main() {
// 初始化链表
Node* head = initList();
// 插入操作
insertAtHead(head, 3);
insertAtTail(head, 5);
insertAtPos(head, 7, 1);
displayList(head);
// 删除操作
deleteAtHead(head);
deleteAtTail(head);
deleteAtPos(head, 0);
displayList(head);
// 查找和更新操作
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found Node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated Node data: %d\n", node->data);
}
else {
printf("Node not found!\n");
}
// 清空链表
clearList(head);
displayList(head);
// 释放链表内存
destroyList(head);
printf("List destroyed.\n");
return 0;
}
4)单向--带头--循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* next;
} Node;
// 创建新节点
Node* createNode(data_t data) {
// 分配新节点的内存空间
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
// 设置新节点的数据和指针
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// 初始化链表
Node* initList() {
// 创建头节点,并将其指针指向自身
Node* head = createNode(0);
head->next = head;
return head;
}
// 头插法
void insertAtHead(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 插入新节点
newNode->next = head->next;
head->next = newNode;
}
// 尾插法
void insertAtTail(Node* head, data_t data) {
// 创建新节点
Node* newNode = createNode(data);
// 找到链表的尾节点
Node* tail = head;
while (tail->next != head) {
tail = tail->next;
}
// 插入新节点
newNode->next = head;
tail->next = newNode;
}
// 指定位置插入
void insertAtPos(Node* head, data_t data, int pos) {
// 检查插入位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return;
}
// 创建新节点
Node* newNode = createNode(data);
// 插入位置不为头部,遍历链表找到插入位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos && temp->next != head) {
temp = temp->next;
count++;
}
// 插入新节点
newNode->next = temp->next;
temp->next = newNode;
}
// 头删法
void deleteAtHead(Node* head) {
// 检查链表是否为空
if (head->next == head) {
printf("The list is empty.\n");
return;
}
// 删除头节点
Node* temp = head->next;
head->next = temp->next;
free(temp);
}
// 尾删法
void deleteAtTail(Node* head) {
// 检查链表是否为空
if (head->next == head) {
printf("The list is empty.\n");
return;
}
// 找到链表的尾节点和尾节点的前一个节点
Node* prev = head;
Node* tail = head->next;
while (tail->next != head) {
prev = tail;
tail = tail->next;
}
// 删除尾节点
prev->next = head;
free(tail);
}
// 指定位置删除
void deleteAtPos(Node* head, int pos) {
// 检查删除位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return;
}
// 遍历链表找到删除位置的前一个节点
Node* temp = head;
int count = 0;
while (count < pos && temp->next != head) {
temp = temp->next;
count++;
}
// 删除位置超出链表长度,位置无效
if (temp->next == head) {
printf("Invalid position.\n");
return;
}
// 删除节点
Node* deletedNode = temp->next;
temp->next = deletedNode->next;
free(deletedNode);
}
// 查找节点
Node* selectNode(Node* head, int pos) {
// 检查查找位置是否合法
if (pos < 0) {
printf("Invalid position.\n");
return NULL;
}
// 遍历链表找到查找位置的节点
Node* temp = head->next;
int count = 0;
while (count < pos && temp != head) {
temp = temp->next;
count++;
}
// 查找位置超出链表长度,位置无效
if (temp == head) {
printf("Invalid position.\n");
return NULL;
}
return temp;
}
// 更新节点
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表
void displayList(Node* head) {
Node* temp = head->next;
while (temp != head) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("HEAD\n");
}
// 清空链表
void clearList(Node* head) {
Node* temp = head->next;
while (temp != head) {
Node* nextNode = temp->next;
free(temp);
temp = nextNode;
}
head->next = head;
}
// 释放链表内存
void destroyList(Node* head) {
clearList(head);
free(head);
}
int main() {
// 初始化链表
Node* head = initList();
// 插入操作
insertAtHead(head, 3);
insertAtTail(head, 5);
insertAtPos(head, 7, 1);
displayList(head);
// 删除操作
deleteAtHead(head);
deleteAtTail(head);
deleteAtPos(head, 0);
displayList(head);
// 查找和更新操作
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found Node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated Node data: %d\n", node->data);
}
else {
printf("Node not found!\n");
}
// 清空链表
clearList(head);
displayList(head);
// 释放链表内存
destroyList(head);
printf("List destroyed.\n");
return 0;
}
5)双向--不带头--不循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* prev;
struct node* next;
} Node;
// 创建新节点,分配内存,并设置节点的数据和指针
Node* createNode(data_t data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// 初始化链表,返回NULL,因为开始时链表是空的
Node* initList() {
return NULL;
}
// 在链表的开头插入新节点
void insertAtHead(Node** head, data_t data) {
Node* newNode = createNode(data);
if (*head != NULL) {
(*head)->prev = newNode;
}
newNode->next = *head;
*head = newNode;
}
// 在链表的末尾插入新节点
void insertAtTail(Node** head, data_t data) {
Node* newNode = createNode(data);
if (*head == NULL) {
*head = newNode;
return;
}
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
// 在链表的指定位置插入新节点
void insertAtPos(Node** head, data_t data, int pos) {
if (pos == 0) {
insertAtHead(head, data);
return;
}
Node* newNode = createNode(data);
Node* temp = *head;
for (int i = 0; i < pos - 1; i++) {
if (temp == NULL) {
printf("Invalid position.\n");
free(newNode);
return;
}
temp = temp->next;
}
newNode->next = temp->next;
newNode->prev = temp;
if (temp->next != NULL) {
temp->next->prev = newNode;
}
temp->next = newNode;
}
// 删除链表的头节点
void deleteAtHead(Node** head) {
if (*head == NULL) {
printf("The list is empty.\n");
return;
}
Node* temp = *head;
*head = (*head)->next;
if (*head != NULL) {
(*head)->prev = NULL;
}
free(temp);
}
// 删除链表的尾节点
void deleteAtTail(Node** head) {
if (*head == NULL) {
printf("The list is empty.\n");
return;
}
Node* temp = *head;
while (temp->next != NULL) {
temp = temp->next;
}
if (temp->prev != NULL) {
temp->prev->next = NULL;
}
else {
*head = NULL;
}
free(temp);
}
// 删除链表的指定位置的节点
void deleteAtPos(Node** head, int pos) {
if (*head == NULL) {
printf("The list is empty.\n");
return;
}
if (pos == 0) {
deleteAtHead(head);
return;
}
Node* temp = *head;
for (int i = 0; i < pos; i++) {
if (temp == NULL) {
printf("Invalid position.\n");
return;
}
temp = temp->next;
}
temp->prev->next = temp->next;
if (temp->next != NULL) {
temp->next->prev = temp->prev;
}
free(temp);
}
// 查找链表的指定位置的节点
Node* selectNode(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp == NULL) {
printf("Invalid position.\n");
return NULL;
}
temp = temp->next;
}
return temp;
}
// 更新节点的数据
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表的数据
void displayList(Node* head) {
Node* temp = head;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 清空链表,删除除头节点外的所有节点
void clearList(Node** head) {
Node* temp = *head;
while (temp != NULL) {
Node* next = temp->next;
free(temp);
temp = next;
}
*head = NULL;
}
// 释放链表的内存,包括头节点
void destroyList(Node** head) {
clearList(head);
}
int main() {
Node* head = initList();
insertAtHead(&head, 3);
insertAtTail(&head, 5);
insertAtPos(&head, 7, 1);
displayList(head);
deleteAtHead(&head);
deleteAtTail(&head);
deleteAtPos(&head, 0);
displayList(head);
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found Node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated Node data: %d\n", node->data);
}
else {
printf("Node not found!\n");
}
clearList(&head);
displayList(head);
destroyList(&head);
printf("List destroyed.\n");
return 0;
}
6)双向--不带头--循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* prev;
struct node* next;
} Node;
// 创建新节点,分配内存,并设置节点的数据和指针
Node* createNode(data_t data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
newNode->data = data;
newNode->prev = newNode; // 链表中的最后一个节点指向自己
newNode->next = newNode; // 链表中的第一个节点指向自己
return newNode;
}
// 初始化链表,返回一个新节点,节点的数据为0
Node* initList() {
return createNode(0);
}
// 在链表的开头插入新节点
void insertAtHead(Node* head, data_t data) {
Node* newNode = createNode(data);
newNode->next = head->next;
newNode->prev = head;
head->next->prev = newNode;
head->next = newNode;
}
// 在链表的末尾插入新节点
void insertAtTail(Node* head, data_t data) {
Node* newNode = createNode(data);
newNode->next = head;
newNode->prev = head->prev;
head->prev->next = newNode;
head->prev = newNode;
}
// 在链表的指定位置插入新节点
void insertAtPos(Node* head, data_t data, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
temp = temp->next;
if (temp == head) {
printf("Invalid position.\n");
return;
}
}
Node* newNode = createNode(data);
newNode->next = temp->next;
newNode->prev = temp;
temp->next->prev = newNode;
temp->next = newNode;
}
// 删除链表的头节点
void deleteAtHead(Node* head) {
if (head->next == head) {
printf("The list is empty.\n");
return;
}
Node* temp = head->next;
temp->next->prev = head;
head->next = temp->next;
free(temp);
}
// 删除链表的尾节点
void deleteAtTail(Node* head) {
if (head->next == head) {
printf("The list is empty.\n");
return;
}
Node* temp = head->prev;
temp->prev->next = head;
head->prev = temp->prev;
free(temp);
}
// 删除链表的指定位置的节点
void deleteAtPos(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
temp = temp->next;
if (temp == head) {
printf("Invalid position.\n");
return;
}
}
temp = temp->next;
if (temp == head) {
printf("Invalid position.\n");
return;
}
temp->prev->next = temp->next;
temp->next->prev = temp->prev;
free(temp);
}
// 查找链表的指定位置的节点
Node* selectNode(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
temp = temp->next;
if (temp == head) {
printf("Invalid position.\n");
return NULL;
}
}
return temp->next;
}
// 更新节点的数据
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表的所有节点
void displayList(Node* head) {
Node* temp = head->next;
while (temp != head) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("HEAD\n");
}
// 清空链表,删除所有节点
void clearList(Node* head) {
Node* temp = head->next;
while (temp != head) {
Node* next = temp->next;
free(temp);
temp = next;
}
head->prev = head;
head->next = head;
}
// 释放链表的内存
void destroyList(Node** headRef) {
clearList(*headRef);
free(*headRef);
*headRef = NULL;
}
// 主函数,测试链表的功能
int main() {
Node* head = initList();
insertAtHead(head, 1);
insertAtTail(head, 2);
insertAtPos(head, 3, 1);
displayList(head);
deleteAtHead(head);
deleteAtTail(head);
deleteAtPos(head, 0);
displayList(head);
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated node data = %d\n", node->data);
}
else {
printf("Node not found!\n");
}
clearList(head);
displayList(head);
destroyList(&head);
printf("List destroyed.\n");
return 0;
}
7)双向--带头--不循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* prev;
struct node* next;
} Node;
// 创建新节点,分配内存,并设置节点的数据和指针
Node* createNode(data_t data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// 初始化链表,返回一个新节点,作为头节点
Node* initList() {
return createNode(0);
}
// 在链表的开头插入新节点
void insertAtHead(Node* head, data_t data) {
Node* newNode = createNode(data);
newNode->next = head->next;
newNode->prev = head;
if (head->next != NULL) {
head->next->prev = newNode;
}
head->next = newNode;
}
// 在链表的末尾插入新节点
void insertAtTail(Node* head, data_t data) {
Node* newNode = createNode(data);
Node* temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
newNode->prev = temp;
temp->next = newNode;
}
// 在链表的指定位置插入新节点
void insertAtPos(Node* head, data_t data, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == NULL) {
printf("Invalid position.\n");
return;
}
temp = temp->next;
}
Node* newNode = createNode(data);
newNode->next = temp->next;
newNode->prev = temp;
if (temp->next != NULL) {
temp->next->prev = newNode;
}
temp->next = newNode;
}
// 删除链表的头节点
void deleteAtHead(Node* head) {
if (head->next == NULL) {
printf("The list is empty.\n");
return;
}
Node* temp = head->next;
head->next = temp->next;
if (temp->next != NULL) {
temp->next->prev = head;
}
free(temp);
}
// 删除链表的尾节点
void deleteAtTail(Node* head) {
if (head->next == NULL) {
printf("The list is empty.\n");
return;
}
Node* temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->prev->next = NULL;
free(temp);
}
// 删除链表的指定位置的节点
void deleteAtPos(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == NULL) {
printf("Invalid position.\n");
return;
}
temp = temp->next;
}
if (temp->next == NULL) {
printf("Invalid position.\n");
return;
}
Node* next = temp->next->next;
if (next != NULL) {
next->prev = temp;
}
free(temp->next);
temp->next = next;
}
// 查找链表的指定位置的节点
Node* selectNode(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == NULL) {
printf("Invalid position.\n");
return NULL;
}
temp = temp->next;
}
return temp->next;
}
// 更新节点的数据
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表的所有节点
void displayList(Node* head) {
Node* temp = head->next;
while (temp != NULL) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 清空链表,删除所有节点
void clearList(Node* head) {
while (head->next != NULL) {
deleteAtHead(head);
}
}
// 释放链表的内存
void destroyList(Node** headRef) {
clearList(*headRef);
free(*headRef);
*headRef = NULL;
}
// 主函数,测试链表的功能
int main() {
Node* head = initList();
insertAtHead(head, 1);
insertAtTail(head, 2);
insertAtPos(head, 3, 1);
displayList(head);
deleteAtHead(head);
deleteAtTail(head);
deleteAtPos(head, 0);
displayList(head);
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated node data = %d\n", node->data);
}
else {
printf("Node not found!\n");
}
clearList(head);
displayList(head);
destroyList(&head);
printf("List destroyed.\n");
return 0;
}
8)双向--带头--循环链表
#include <stdio.h>
#include <stdlib.h>
typedef int data_t;
typedef struct node {
data_t data;
struct node* prev;
struct node* next;
} Node;
// 创建新节点,分配内存,并设置节点的数据和指针
Node* createNode(data_t data) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (!newNode) {
printf("Memory allocation failed. The program will exit.\n");
exit(-1);
}
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}
// 初始化链表,返回一个新节点,作为头节点
Node* initList() {
Node* head = createNode(0);
head->next = head;
head->prev = head;
return head;
}
// 在链表的开头插入新节点
void insertAtHead(Node* head, data_t data) {
Node* newNode = createNode(data);
newNode->next = head->next;
newNode->prev = head;
head->next->prev = newNode;
head->next = newNode;
}
// 在链表的末尾插入新节点
void insertAtTail(Node* head, data_t data) {
Node* newNode = createNode(data);
newNode->next = head;
newNode->prev = head->prev;
head->prev->next = newNode;
head->prev = newNode;
}
// 在链表的指定位置插入新节点
void insertAtPos(Node* head, data_t data, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == head) {
printf("Invalid position.\n");
return;
}
temp = temp->next;
}
Node* newNode = createNode(data);
newNode->next = temp->next;
newNode->prev = temp;
temp->next->prev = newNode;
temp->next = newNode;
}
// 删除链表的头节点
void deleteAtHead(Node* head) {
if (head->next == head) {
printf("The list is empty.\n");
return;
}
Node* temp = head->next;
head->next = temp->next;
temp->next->prev = head;
free(temp);
}
// 删除链表的尾节点
void deleteAtTail(Node* head) {
if (head->next == head) {
printf("The list is empty.\n");
return;
}
Node* temp = head->prev;
head->prev = temp->prev;
temp->prev->next = head;
free(temp);
}
// 删除链表的指定位置的节点
void deleteAtPos(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == head) {
printf("Invalid position.\n");
return;
}
temp = temp->next;
}
if (temp->next == head) {
printf("Invalid position.\n");
return;
}
Node* next = temp->next->next;
next->prev = temp;
free(temp->next);
temp->next = next;
}
// 查找链表的指定位置的节点
Node* selectNode(Node* head, int pos) {
Node* temp = head;
for (int i = 0; i < pos; i++) {
if (temp->next == head) {
printf("Invalid position.\n");
return NULL;
}
temp = temp->next;
}
if (temp->next == head) {
printf("Invalid position.\n");
return NULL;
}
return temp->next;
}
// 更新节点的数据
void updateNode(Node* node, data_t newData) {
if (node != NULL) {
node->data = newData;
}
else {
printf("Node not found.\n");
}
}
// 打印链表的所有节点
void displayList(Node* head) {
Node* temp = head->next;
while (temp != head) {
printf("%d -> ", temp->data);
temp = temp->next;
}
printf("NULL\n");
}
// 清空链表,删除所有节点
void clearList(Node* head) {
while (head->next != head) {
deleteAtHead(head);
}
}
// 释放链表的内存
void destroyList(Node** headRef) {
clearList(*headRef);
free(*headRef);
*headRef = NULL;
}
// 主函数,测试链表的功能
int main() {
Node* head = initList();
insertAtHead(head, 1);
insertAtTail(head, 2);
insertAtPos(head, 3, 1);
displayList(head);
deleteAtHead(head);
deleteAtTail(head);
deleteAtPos(head, 0);
displayList(head);
Node* node = selectNode(head, 0);
if (node != NULL) {
printf("Found node with data = %d\n", node->data);
updateNode(node, 10);
printf("Updated node data = %d\n", node->data);
}
else {
printf("Node not found!\n");
}
clearList(head);
displayList(head);
destroyList(&head);
printf("List destroyed.\n");
return 0;
}
参考资料:
- 程杰:《大话数据结构》
- 王晓华:《算法的乐趣》
- 严蔚敏、吴伟民:《数据结构(C语言版)》
- 渡部有隆:《挑战程序设计竞赛2》
- 石田保辉:《我的第一本算法书》