赞
踩
单向循环链表是一种特殊的单链表,其中最后一个节点的后继指针指向头节点,形成一个环。单向循环链表适合用于需要循环访问数据的场景,如约瑟夫环问题。
节点定义
每个节点包含两个部分:数据域和指针域。
- typedef struct Node {
- int data; // 数据域,存储节点的值
- struct Node *next; // 指针域,指向下一个节点
- } Node;
结构定义
单向循环链表包含一个头指针和链表中的节点个数。
- typedef struct {
- Node *head; // 指向单向循环链表的头节点
- size_t size; // 单向循环链表中的节点个数
- } CircularLinkedList;
单向链表和单向循环链表的区别
单向链表(Singly Linked List):
NULL
,表示链表的结束。单向循环链表(Singly Circular Linked List):
单向链表:
单向循环链表:
单向链表的优缺点
优点:
缺点:
单向循环链表的优缺点
优点:
缺点:
初始化单向循环链表:
插入新节点:
删除节点:
获取指定位置的元素:
修改指定位置的元素:
释放单向循环链表内存:
- void initCircularLinkedList(CircularLinkedList *list) {
- list->head = NULL; // 初始化头节点为空
- list->size = 0; // 初始化节点个数为0
- }
CircularLinkedList *list
,指向需要初始化的链表结构。head
设置为 NULL
。size
设置为 0
。
在单向循环链表的指定位置插入新节点。
- void insertAt(CircularLinkedList *list, size_t index, int element) {
- if (index > list->size) {
- return; // 忽略无效的插入位置
- }
-
- Node *newNode = (Node *)malloc(sizeof(Node)); // 创建新节点
- newNode->data = element;
-
- if (index == 0) { // 插入位置是头节点
- if (list->head == NULL) { // 如果链表为空
- newNode->next = newNode;
- list->head = newNode;
- } else {
- Node *tail = list->head;
- while (tail->next != list->head) {
- tail = tail->next;
- }
- newNode->next = list->head;
- list->head = newNode;
- tail->next = newNode;
- }
- } else {
- Node *prevNode = list->head;
- for (size_t i = 0; i < index - 1; i++) {
- prevNode = prevNode->next;
- }
- newNode->next = prevNode->next;
- prevNode->next = newNode;
- }
-
- list->size++; // 更新节点个数
- }
CircularLinkedList *list
,指向链表结构。size_t index
,插入位置的索引。int element
,插入节点的值。next
指针指向自己,并将 head
指针指向新节点。
删除指定位置的节点并返回被删除的元素。
- int deleteAt(CircularLinkedList *list, size_t index) {
- if (index >= list->size) {
- return -1; // 忽略无效的删除位置
- }
-
- int deletedElement;
-
- if (index == 0) { // 删除位置是头节点
- Node *temp = list->head;
- if (list->head->next == list->head) { // 如果链表只有一个节点
- list->head = NULL;
- } else {
- Node *tail = list->head;
- while (tail->next != list->head) {
- tail = tail->next;
- }
- list->head = temp->next;
- tail->next = list->head;
- }
- deletedElement = temp->data;
- free(temp); // 释放被删除节点的内存
- } else {
- Node *prevNode = list->head;
- for (size_t i = 0; i < index - 1; i++) {
- prevNode = prevNode->next;
- }
- Node *temp = prevNode->next;
- prevNode->next = temp->next;
- deletedElement = temp->data;
- free(temp); // 释放被删除节点的内存
- }
-
- list->size--; // 更新节点个数
- return deletedElement;
- }
CircularLinkedList *list
,指向链表结构。size_t index
,删除位置的索引。-1
。head
指针置为 NULL
。- // 获取指定位置的元素
- int getElementAt(const CircularLinkedList *list, size_t index) {
- if (index >= list->size) {
- return -1; // 返回无效的索引
- }
-
- Node *currentNode = list->head;
- for (size_t i = 0; i < index; i++) {
- currentNode = currentNode->next;
- }
-
- return currentNode->data; // 返回指定位置的元素
- }
const CircularLinkedList *list
,指向链表结构。size_t index
,目标位置的索引。-1
。- // 修改指定位置的元素
- void modifyAt(CircularLinkedList *list, size_t index, int newValue) {
- if (index >= list->size) {
- return; // 忽略无效的修改位置
- }
-
- Node *currentNode = list->head;
- for (size_t i = 0; i < index; i++) {
- currentNode = currentNode->next;
- }
-
- currentNode->data = newValue; // 修改节点的值
- }
CircularLinkedList *list
,指向链表结构。size_t index
,目标位置的索引。int newValue
,新值。- void printCircularLinkedList(const CircularLinkedList *list) {
- if (list->head == NULL) {
- printf("链表为空\n");
- return;
- }
- Node *currentNode = list->head;
- do {
- printf("%d ", currentNode->data);
- currentNode = currentNode->next;
- } while (currentNode != list->head);
- printf("\n");
- }
const CircularLinkedList *list
,指向需要打印的链表结构。
- void destroyCircularLinkedList(CircularLinkedList *list) {
- if (list->head == NULL) {
- return;
- }
- Node *currentNode = list->head;
- Node *nextNode;
- do {
- nextNode = currentNode->next;
- free(currentNode);
- currentNode = nextNode;
- } while (currentNode != list->head);
-
- list->head = NULL;
- list->size = 0;
- }
CircularLinkedList *list
,指向需要释放的链表结构。head
置为 NULL
,将链表的节点个数 size
置为 0
。以下是一个完整的单向循环链表实现代码,包括初始化、插入、删除、获取和修改元素,以及释放链表的内存的所有基本操作:
- #include <stdio.h>
- #include <stdlib.h>
-
- // 单向循环链表节点结构定义
- typedef struct Node {
- int data; // 节点存储的数据
- struct Node *next; // 指向下一个节点的指针
- } Node;
-
- // 单向循环链表结构定义
- typedef struct {
- Node *head; // 单向循环链表头节点指针
- size_t size; // 单向循环链表中的节点个数
- } CircularLinkedList;
-
- // 初始化单向循环链表
- void initCircularLinkedList(CircularLinkedList *list) {
- list->head = NULL; // 初始化头节点为空
- list->size = 0; // 初始化节点个数为0
- }
-
- // 在指定位置插入元素
- void insertAt(CircularLinkedList *list, size_t index, int element) {
- if (index > list->size) {
- return; // 忽略无效的插入位置
- }
-
- Node *newNode = (Node *)malloc(sizeof(Node)); // 创建新节点
- newNode->data = element;
-
- if (index == 0) { // 插入位置是头节点
- if (list->head == NULL) { // 如果链表为空
- newNode->next = newNode;
- list->head = newNode;
- } else {
- Node *tail = list->head;
- while (tail->next != list->head) {
- tail = tail->next;
- }
- newNode->next = list->head;
- list->head = newNode;
- tail->next = newNode;
- }
- } else {
- Node *prevNode = list->head;
- for (size_t i = 0; i < index - 1; i++) {
- prevNode = prevNode->next;
- }
- newNode->next = prevNode->next;
- prevNode->next = newNode;
- }
-
- list->size++; // 更新节点个数
- }
-
- // 删除指定位置的元素并返回被删除的元素
- int deleteAt(CircularLinkedList *list, size_t index) {
- if (index >= list->size) {
- return -1; // 忽略无效的删除位置
- }
-
- int deletedElement;
-
- if (index == 0) { // 删除位置是头节点
- Node *temp = list->head;
- if (list->head->next == list->head) { // 如果链表只有一个节点
- list->head = NULL;
- } else {
- Node *tail = list->head;
- while (tail->next != list->head) {
- tail = tail->next;
- }
- list->head = temp->next;
- tail->next = list->head;
- }
- deletedElement = temp->data;
- free(temp); // 释放被删除节点的内存
- } else {
- Node *prevNode = list->head;
- for (size_t i = 0; i < index - 1; i++) {
- prevNode = prevNode->next;
- }
- Node *temp = prevNode->next;
- prevNode->next = temp->next;
- deletedElement = temp->data;
- free(temp); // 释放被删除节点的内存
- }
-
- list->size--; // 更新节点个数
- return deletedElement;
- }
-
- // 获取指定位置的元素
- int getElementAt(const CircularLinkedList *list, size_t index) {
- if (index >= list->size) {
- return -1; // 返回无效的索引
- }
-
- Node *currentNode = list->head;
- for (size_t i = 0; i < index; i++) {
- currentNode = currentNode->next;
- }
-
- return currentNode->data; // 返回指定位置的元素
- }
-
- // 修改指定位置的元素
- void modifyAt(CircularLinkedList *list, size_t index, int newValue) {
- if (index >= list->size) {
- return; // 忽略无效的修改位置
- }
-
- Node *currentNode = list->head;
- for (size_t i = 0; i < index; i++) {
- currentNode = currentNode->next;
- }
-
- currentNode->data = newValue; // 修改节点的值
- }
-
- // 释放单向循环链表内存
- void destroyCircularLinkedList(CircularLinkedList *list) {
- if (list->head == NULL) {
- return;
- }
- Node *currentNode = list->head;
- Node *nextNode;
- do {
- nextNode = currentNode->next;
- free(currentNode);
- currentNode = nextNode;
- } while (currentNode != list->head);
-
- list->head = NULL;
- list->size = 0;
- }
-
- // 打印单向循环链表中的所有元素
- void printCircularLinkedList(const CircularLinkedList *list) {
- if (list->head == NULL) {
- printf("链表为空\n");
- return;
- }
- Node *currentNode = list->head;
- do {
- printf("%d ", currentNode->data);
- currentNode = currentNode->next;
- } while (currentNode != list->head);
- printf("\n");
- }
-
- // 主函数测试单向循环链表操作
- int main() {
- CircularLinkedList myList; // 声明单向循环链表
-
- initCircularLinkedList(&myList); // 初始化单向循环链表
- printf("初始化单向循环链表成功!\n");
-
- insertAt(&myList, 0, 1); // 在索引0处插入元素1
- insertAt(&myList, 1, 2); // 在索引1处插入元素2
- insertAt(&myList, 2, 3); // 在索引2处插入元素3
- printf("向单向循环链表插入了3个元素\n");
- printCircularLinkedList(&myList); // 打印链表中的元素
-
- printf("单向循环链表长度为: %zu\n", myList.size); // 获取单向循环链表长度
-
- insertAt(&myList, 1, 4); // 在索引1处插入元素4
- printf("在索引1处插入元素4\n");
- printCircularLinkedList(&myList); // 打印链表中的元素
-
- printf("单向循环链表长度为: %zu\n", myList.size); // 再次获取单向循环链表长度
-
- printf("删除索引1处的元素,该元素值是: %d\n", deleteAt(&myList, 1)); // 删除索引1处的元素
- printCircularLinkedList(&myList); // 打印链表中的元素
-
- destroyCircularLinkedList(&myList); // 销毁单向循环链表
- printf("单向循环链表销毁成功!\n");
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。