注: 空链表状态头节点的前驱、后继节点都指向自己
代码部分
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct node {
int data;
struct node *prev;
struct node *next;
}NODE, *PNODE;
void init(PNODE *);
bool is_empty(PNODE);
void traverse(PNODE);
bool head_add(PNODE, int);
bool rear_add(PNODE, int);
int len(PNODE);
bool insert(PNODE, int, int);
bool delete(PNODE, int, int *);
bool clear(PNODE);
bool clear(PNODE head)
{
PNODE p, q;
printf("clear...");
if (NULL == head) {
printf(" 未初始化无需操作\n");
return false;
}
p = head->next;
while (p != head) {
q = p->next;
p = q->next;
// 有头节点的循环链表需要操作这一步
head->next = p;
free(q);
}
printf("成功\n");
return true;
}
bool delete(PNODE head, int pos, int *pVal)
{
PNODE p;
int i = 0;
printf("delete pos %d", pos);
if (NULL == head) {
printf(" 失败,链表未初始化\n");
return false;
}
if (pos < 1 || pos > len(head)) {
printf(" 失败, 无效的位置\n");
return false;
}
p = head;
while (i < pos) {
p = p->next;
++i;
}
*pVal = p->data;
p->prev->next = p->next;
p->next->prev = p->prev;
free(p);
printf(" 成功,值为%d\n", *pVal);
return true;
}
bool insert(PNODE head, int pos, int val)
{
PNODE p, tmp;
int i = 0;
printf("insert pos %d, val %d", pos, val);
if (NULL == head) {
printf(" 失败,链表未初始化!\n");
return false;
}
if (pos < 1 || pos > len(head)+1) {
printf(" 失败, 插入位置无效\n");
return false;
}
// 找插入位置的前驱节点,如果空链表,则p指向的是头节点
p = head;
while (i < pos-1) {
p = p->next;
++i;
}
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf("内存分配失败!\n");
return false;
}
tmp->data = val;
tmp->prev = p;
tmp->next = p->next;
p->next->prev = tmp;
p->next = tmp;
printf(" 成功\n");
return true;
}
int len(PNODE head)
{
PNODE p;
int i = 0;
if (NULL == head) {
printf(" 失败,链表未初始化!\n");
return false;
}
p = head->next;
while (p != head) {
++i;
p = p->next;
}
return i;
}
bool rear_add(PNODE head, int val)
{
printf("rear_add %d", val);
PNODE tmp;
if (NULL == head) {
printf(" 失败,链表未初始化!\n");
return false;
}
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf(" 内存分配失败!\n");
return false;
}
tmp->data = val;
tmp->prev = head->prev;
tmp->next = head;
head->prev->next = tmp;
head->prev = tmp;
printf(" 成功\n");
return true;
}
bool head_add(PNODE head, int val)
{
printf("head_add %d", val);
PNODE tmp;
if (NULL == head) {
printf(" 失败,链表未初始化!\n");
return false;
}
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf(" 内存分配失败!\n");
return false;
}
tmp->data = val;
tmp->prev = head;
tmp->next = head->next;
head->next->prev = tmp;
head->next = tmp;
printf(" 成功\n");
return true;
}
void traverse(PNODE head)
{
PNODE p;
int i = 1;
if (is_empty(head)) {
printf("链表为空\n");
return;
}
p = head->next;
while (p != head) {
printf("node %d: prev(%p) data(%d) next(%p)\n", i, p->prev, p->data, p->next);
p = p->next;
++i;
}
}
bool is_empty(PNODE head)
{
if (head == head->next)
return true;
return false;
}
void init(PNODE *pHead)
{
PNODE tmp, head;
int val;
head = (PNODE)malloc(sizeof(NODE));
head->prev = head->next = head;
printf("请输入所有节点的值:\n");
while(1) {
scanf("%d", &val);
if (val == 0) {
printf("初始化完毕!\n");
break;
}
tmp = (PNODE)malloc(sizeof(NODE));
if (! tmp) {
printf("内存分配失败!\n");
return;
}
tmp->data = val;
tmp->prev = head->prev;
tmp->next = head;
head->prev->next = tmp;
head->prev = tmp;
}
*pHead = head;
}
int main(void)
{
PNODE head = NULL;
int val;
head_add(head, 13);
init(&head);
traverse(head);
head_add(head, 13);
head_add(head, 12);
head_add(head, 11);
traverse(head);
rear_add(head, 31);
rear_add(head, 32);
rear_add(head, 33);
traverse(head);
printf("链表长度: %d\n", len(head));
insert(head, 0, 100);
insert(head, 50, 100);
insert(head, 1, 9);
insert(head, 1, 8);
insert(head, 3, 10);
insert(head, 13, 34);
traverse(head);
printf("链表长度: %d\n", len(head));
delete(head, 5, &val);
traverse(head);
printf("链表长度: %d\n", len(head));
clear(head);
printf("链表长度: %d\n", len(head));
return 0;
}
output
[root@8be225462e66 c]# gcc circular_doubly_linklist.c && ./a.out
head_add 13 失败,链表未初始化!
请输入所有节点的值:
21 22 23 0
初始化完毕!
node 1: prev(0x20e96b0) data(21) next(0x20e9b00)
node 2: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 3: prev(0x20e9b00) data(23) next(0x20e96b0)
head_add 13 成功
head_add 12 成功
head_add 11 成功
node 1: prev(0x20e96b0) data(11) next(0x20e9b60)
node 2: prev(0x20e9b80) data(12) next(0x20e9b40)
node 3: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 4: prev(0x20e9b40) data(21) next(0x20e9b00)
node 5: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 6: prev(0x20e9b00) data(23) next(0x20e96b0)
rear_add 31 成功
rear_add 32 成功
rear_add 33 成功
node 1: prev(0x20e96b0) data(11) next(0x20e9b60)
node 2: prev(0x20e9b80) data(12) next(0x20e9b40)
node 3: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 4: prev(0x20e9b40) data(21) next(0x20e9b00)
node 5: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 6: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 7: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 8: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 9: prev(0x20e9bc0) data(33) next(0x20e96b0)
链表长度: 9
insert pos 0, val 100 失败, 插入位置无效
insert pos 50, val 100 失败, 插入位置无效
insert pos 1, val 9 成功
insert pos 1, val 8 成功
insert pos 3, val 10 成功
insert pos 13, val 34 成功
node 1: prev(0x20e96b0) data(8) next(0x20e9c00)
node 2: prev(0x20e9c20) data(9) next(0x20e9c40)
node 3: prev(0x20e9c00) data(10) next(0x20e9b80)
node 4: prev(0x20e9c40) data(11) next(0x20e9b60)
node 5: prev(0x20e9b80) data(12) next(0x20e9b40)
node 6: prev(0x20e9b60) data(13) next(0x20e9ae0)
node 7: prev(0x20e9b40) data(21) next(0x20e9b00)
node 8: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 9: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 10: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 11: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 12: prev(0x20e9bc0) data(33) next(0x20e9c60)
node 13: prev(0x20e9be0) data(34) next(0x20e96b0)
链表长度: 13
delete pos 5 成功,值为12
node 1: prev(0x20e96b0) data(8) next(0x20e9c00)
node 2: prev(0x20e9c20) data(9) next(0x20e9c40)
node 3: prev(0x20e9c00) data(10) next(0x20e9b80)
node 4: prev(0x20e9c40) data(11) next(0x20e9b40)
node 5: prev(0x20e9b80) data(13) next(0x20e9ae0)
node 6: prev(0x20e9b40) data(21) next(0x20e9b00)
node 7: prev(0x20e9ae0) data(22) next(0x20e9b20)
node 8: prev(0x20e9b00) data(23) next(0x20e9ba0)
node 9: prev(0x20e9b20) data(31) next(0x20e9bc0)
node 10: prev(0x20e9ba0) data(32) next(0x20e9be0)
node 11: prev(0x20e9bc0) data(33) next(0x20e9c60)
node 12: prev(0x20e9be0) data(34) next(0x20e96b0)
链表长度: 12
clear...成功
链表长度: 0
[root@8be225462e66 c]#