C 中循环单链表的优雅实现

c++

1个回答

写回答

Liuguonan

2025-07-09 23:57

+ 关注

AI
AI

使用循环单链表(Circular Linked List)是一种优雅的方式来存储和操作数据。循环单链表是一种特殊的链表,其中最后一个节点的下一个指针指向第一个节点,形成一个循环。这种数据结构在许多应用中都有广泛的应用,例如游戏中的循环队列、循环缓冲区等。

在C语言中,我们可以通过定义一个结构体来表示循环单链表的节点。节点包含两个成员变量,一个是存储数据的变量,另一个是指向下一个节点的指针。我们还可以定义一个指向循环单链表第一个节点的指针,用于操作链表。

下面是一个使用循环单链表存储整数的案例代码:

c

#include <stdio.h>

#include <stdlib.h>

// 定义循环单链表的节点结构体

typedef struct Node {

int data;

struct Node* next;

} Node;

// 在循环单链表末尾插入节点

void insert(Node<strong> head, int data) {

// 创建新节点

Node* newNode = (Node*)malloc(sizeof(Node));

newNode->data = data;

// 如果链表为空,则将新节点作为第一个节点

if (*head == NULL) {

*head = newNode;

newNode->next = newNode;

}

else {

// 找到链表的最后一个节点

Node* last = *head;

while (last->next != *head) {

last = last->next;

}

// 将新节点插入到链表末尾

last->next = newNode;

newNode->next = *head;

}

}

// 在循环单链表中删除指定节点

void delete(Node</strong> head, int key) {

// 如果链表为空,则直接返回

if (*head == NULL) {

return;

}

// 如果链表只有一个节点且为要删除的节点,则释放内存并将头指针置空

if ((*head)->data == key && (*head)->next == *head) {

free(*head);

*head = NULL;

return;

}

// 如果要删除的节点是第一个节点,则需要更新头指针

if ((*head)->data == key) {

Node* last = *head;

while (last->next != *head) {

last = last->next;

}

last->next = (*head)->next;

free(*head);

*head = last->next;

}

else {

// 找到要删除的节点的前一个节点

Node* prev = *head;

while (prev->next != *head && prev->next->data != key) {

prev = prev->next;

}

// 如果找到了要删除的节点,则更新链表指针并释放内存

if (prev->next->data == key) {

Node* temp = prev->next;

prev->next = temp->next;

free(temp);

}

}

}

// 在循环单链表中打印所有节点的数据

void printList(Node* head) {

if (head == NULL) {

printf("链表为空\n");

}

else {

Node* current = head;

do {

printf("%d ", current->data);

current = current->next;

} while (current != head);

printf("\n");

}

}

int mAIn() {

Node* head = NULL;

// 在循环单链表中插入节点

insert(&head, 1);

insert(&head, 2);

insert(&head, 3);

insert(&head, 4);

// 打印循环单链表中的节点数据

printf("循环单链表的节点数据:");

printList(head);

// 在循环单链表中删除节点

delete(&head, 2);

// 再次打印循环单链表中的节点数据

printf("删除节点后的循环单链表的节点数据:");

printList(head);

return 0;

}

插入和删除节点

在循环单链表中,插入和删除节点是两个常见的操作。插入节点的操作可以分为两种情况:如果链表为空,则将新节点作为第一个节点;如果链表不为空,则找到链表的最后一个节点,将新节点插入到链表末尾。删除节点的操作也可以分为几种情况:如果链表为空,则直接返回;如果链表只有一个节点且为要删除的节点,则释放内存并将头指针置空;如果要删除的节点是第一个节点,则需要更新头指针;如果要删除的节点是其他节点,则找到要删除的节点的前一个节点,更新链表指针并释放内存。

打印节点数据

为了方便查看循环单链表中的节点数据,我们可以定义一个函数来打印所有节点的数据。该函数首先检查链表是否为空,如果为空则打印相应的提示信息。否则,从第一个节点开始遍历链表,打印每个节点的数据,直到回到第一个节点为止。

以上就是使用循环单链表实现存储和操作数据的方法。循环单链表的优雅之处在于它能够充分利用链表的特性,同时也减少了对头指针的操作。通过合理地设计节点结构体和相关操作函数,我们可以更加方便地使用循环单链表来解决问题。

举报有用(4)分享收藏

Copyright © 2025 IZhiDa.com All Rights Reserved.

知答 版权所有 粤ICP备2023042255号