使用C语言实现双向链表的全部功能
时间: 2023-12-22 07:03:58 浏览: 109
双向链表(Doubly Linked List)是一种数据结构,它与单向链表相似,但是每个节点除了指向下一个节点的指针之外,还有一个指向上一个节点的指针。这使得在双向链表中可以方便地向前或向后遍历节点。以下是使用C语言实现双向链表的全部功能的代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义双向链表的节点结构体
typedef struct Node {
int data;
struct Node* prev;
struct Node* next;
} Node;
// 初始化双向链表
Node* init() {
Node* head = (Node*)malloc(sizeof(Node));
head->data = -1;
head->prev = NULL;
head->next = NULL;
return head;
}
// 在双向链表末尾添加节点
void append(Node* head, int data) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = data;
new_node->prev = head;
new_node->next = NULL;
Node* p = head;
while (p->next != NULL) {
p = p->next;
}
p->next = new_node;
}
// 在双向链表指定位置插入节点
void insert(Node* head, int pos, int data) {
Node* new_node = (Node*)malloc(sizeof(Node));
new_node->data = data;
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == NULL) {
printf("Error: position out of range\n");
return;
}
}
new_node->prev = p->prev;
new_node->next = p;
p->prev->next = new_node;
p->prev = new_node;
}
// 删除双向链表指定位置的节点
void remove_node(Node* head, int pos) {
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == NULL) {
printf("Error: position out of range\n");
return;
}
}
p->prev->next = p->next;
if (p->next != NULL) {
p->next->prev = p->prev;
}
free(p);
}
// 获取双向链表指定位置的节点的数据
int get(Node* head, int pos) {
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == NULL) {
printf("Error: position out of range\n");
return -1;
}
}
return p->data;
}
// 修改双向链表指定位置的节点的数据
void set(Node* head, int pos, int data) {
Node* p = head;
for (int i = 0; i < pos; i++) {
p = p->next;
if (p == NULL) {
printf("Error: position out of range\n");
return;
}
}
p->data = data;
}
// 获取双向链表的长度
int length(Node* head) {
Node* p = head;
int len = 0;
while (p->next != NULL) {
len++;
p = p->next;
}
return len;
}
// 打印双向链表的所有节点的数据
void print(Node* head) {
Node* p = head->next;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
// 反向打印双向链表的所有节点的数据
void reverse_print(Node* head) {
Node* p = head;
while (p->next != NULL) {
p = p->next;
}
while (p->prev != NULL) {
printf("%d ", p->data);
p = p->prev;
}
printf("\n");
}
// 释放双向链表的所有节点的内存
void destroy(Node* head) {
Node* p = head->next;
while (p != NULL) {
Node* q = p;
p = p->next;
free(q);
}
free(head);
}
int main() {
Node* head = init();
append(head, 1);
append(head, 2);
append(head, 3);
insert(head, 1, 4);
remove_node(head, 2);
set(head, 2, 5);
printf("Length: %d\n", length(head));
print(head);
reverse_print(head);
destroy(head);
return 0;
}
```
在上面的代码中,`init`函数用于初始化双向链表,返回一个头节点;`append`函数用于在双向链表末尾添加一个节点;`insert`函数用于在双向链表指定位置插入一个节点;`remove_node`函数用于删除双向链表指定位置的节点;`get`函数用于获取双向链表指定位置的节点的数据;`set`函数用于修改双向链表指定位置的节点的数据;`length`函数用于获取双向链表的长度;`print`函数用于打印双向链表的所有节点的数据;`reverse_print`函数用于反向打印双向链表的所有节点的数据;`destroy`函数用于释放双向链表的所有节点的内存。在`main`函数中,我们对双向链表进行了一些操作,例如添加节点、插入节点、删除节点、修改节点、获取长度、打印节点等等。最后,我们使用`destroy`函数释放了双向链表的内存。
阅读全文