c语言建立一个双向循环链表
时间: 2024-05-03 21:19:11 浏览: 13
双向循环链表是一种具有双向循环性质的链表,它可以实现在链表中任意位置的插入和删除操作。下面是一个简单的双向循环链表的C语言代码实现:
```c
#include <stdio.h>
#include <stdlib.h>
// 双向循环链表结点定义
typedef struct Node {
int data;
struct Node *prev;
struct Node *next;
} Node;
// 创建结点函数
Node *create_node(int data) {
Node *new_node = (Node *)malloc(sizeof(Node));
if (new_node == NULL) {
printf("Memory allocation failed!\n");
exit(1);
}
new_node->data = data;
new_node->prev = NULL;
new_node->next = NULL;
return new_node;
}
// 在链表尾部插入结点
void insert_tail(Node **head, int data) {
Node *new_node = create_node(data);
if (*head == NULL) {
*head = new_node;
(*head)->next = (*head)->prev = *head;
return;
}
Node *tail = (*head)->prev;
new_node->prev = tail;
new_node->next = *head;
tail->next = new_node;
(*head)->prev = new_node;
}
// 在链表头部插入结点
void insert_head(Node **head, int data) {
Node *new_node = create_node(data);
if (*head == NULL) {
*head = new_node;
(*head)->next = (*head)->prev = *head;
return;
}
Node *tail = (*head)->prev;
new_node->prev = tail;
new_node->next = *head;
tail->next = new_node;
(*head)->prev = new_node;
*head = new_node;
}
// 删除链表中的指定结点
void delete_node(Node **head, Node *target) {
if (*head == NULL || target == NULL) {
return;
}
if (*head == target) {
*head = target->next;
}
target->prev->next = target->next;
target->next->prev = target->prev;
free(target);
}
// 打印链表
void print_list(Node *head) {
if (head == NULL) {
printf("The list is empty!\n");
return;
}
Node *cur = head;
do {
printf("%d ", cur->data);
cur = cur->next;
} while (cur != head);
printf("\n");
}
// 测试
int main() {
Node *head = NULL;
insert_tail(&head, 1);
insert_tail(&head, 2);
insert_head(&head, 3);
insert_head(&head, 4);
print_list(head); // 4 3 1 2
delete_node(&head, head);
delete_node(&head, head->prev);
print_list(head); // 1 2
return 0;
}
```
在上面的代码中,我们定义了一个 `Node` 结构体来表示链表中的结点,其中包括了结点的数据域、指向前一个结点的指针 `prev` 和指向后一个结点的指针 `next`。我们还定义了 `create_node` 函数来创建新的结点,以及 `insert_tail`、`insert_head` 和 `delete_node` 函数来实现在链表尾部、头部插入结点和删除指定结点的操作。最后,我们还定义了 `print_list` 函数来打印链表的所有元素。在 `main` 函数中,我们测试了上述几种操作,并打印了链表中的所有元素。