环状双向链表创建,删除,插入,遍历详细讲解
#include<stdio.h>
#include<stdlib.h>typedef int data_t;
typedef struct node
{data_t data;struct node* next;struct node* prev;
}node_t;// 函数声明
int dclist_create(node_t** head, data_t data);
static void __dclist_insert(node_t* prev, node_t* pnew, node_t* next);
int dclist_insert(node_t** head, data_t data);
static void __dclist_delete(node_t* prev, node_t* p, node_t* next);
int dclist_delete(node_t** head, data_t data);
node_t* dclist_query(node_t* head, data_t data);
void dclist_showall(node_t* head);int dclist_create(node_t** head, data_t data)
{node_t* pnew = (node_t*)malloc(sizeof(node_t));if (pnew == NULL)return -1;pnew->data = data;pnew->prev = pnew;pnew->next = pnew;*head = pnew;return 0;
}static void __dclist_insert(node_t* prev, node_t* pnew, node_t* next)
{pnew->next = next;pnew->prev = prev;prev->next = pnew;next->prev = pnew;
}int dclist_insert(node_t** head, data_t data)
{node_t* pnew = (node_t*)malloc(sizeof(node_t));if (pnew == NULL)return -1;pnew->data = data;if (*head == NULL) // 修正比较运算符{pnew->prev = pnew;pnew->next = pnew;*head = pnew;return 0;}else{__dclist_insert((*head)->prev, pnew, *head);return 0;}
}static void __dclist_delete(node_t* prev, node_t* p, node_t* next)
{prev->next = next;next->prev = prev; // 修正指针连接free(p); // 释放被删除的节点
}int dclist_delete(node_t** head, data_t data)
{if (*head == NULL) return -1; // 空链表检查node_t* p = dclist_query(*head, data);if (p == NULL)return -1;if (p == *head){if (p->next == p) // 只有一个节点{free(p);*head = NULL;return 0;}*head = p->next; // 更新头指针}__dclist_delete(p->prev, p, p->next);return 0;
}node_t* dclist_query(node_t* head, data_t data)
{if (head == NULL) return NULL; // 空链表检查node_t* p = head;do {if (p->data == data)return p;p = p->next;} while (p != head);return NULL;
}void dclist_showall(node_t* head)
{if (head == NULL) {printf("空链表\n");return;}node_t* p = head;do {printf("%3d", p->data);p = p->next;} while (p != head);printf("\n");
}int main()
{node_t* head = NULL;dclist_create(&head, 888);for (int i = 1; i < 6; i++)dclist_insert(&head, i);printf("初始链表:\n");dclist_showall(head);while (1){printf("请输入删除数据(-1退出):");data_t data;if (scanf_s("%d", &data) != 1){printf("输入无效,请重新输入。\n");while (getchar() != '\n');continue;}if (data == -1)break;if (dclist_delete(&head, data) == -1){printf("删除失败,请重试...\n");continue;}printf("删除后的链表:\n");dclist_showall(head);}// 清理剩余节点while (head != NULL) {dclist_delete(&head, head->data);}return 0;
}
运行结果: