双向循环链表是一种链式存储结构,它的最后一个结点指向头结点,形成一个环。因此,从循环链表中的任何一个结点出发都能找到任何其他结点。双向循环链表的操作和双向链表的操作基本一致,差别仅仅在于算法中的循环条件有所不同。双向循环链表的头结点的前驱指向最后一个结点,尾结点的后继指向头结点。
注意:双向循环链表中无其他结点,只有头结点时 ,头结点的前驱和后继度指向自身。
1、双向循环链表的存储结构
typedef int ElemType;
typedef struct CycNode
{
struct CycNode *prev;
ElemType data;
struct CycNode *next;
}CycNode;
typedef struct CycDouList
{
CycNode *head;
int count;
}CycDouList, *pCycDouList;
2、双向循环链表的初始化
void InitCycDouList(pCycDouList list) //初始化函数
{
assert(list != NULL);
list->head = NULL;
list->count = 0;
}
3、双向循环链表的扩充
static CycNode *BuyNode(ElemType value, CycNode *prev, CycNode* next)
{
CycNode * s = (CycNode *)malloc(sizeof(CycNode));
assert(s != NULL);
s->data = value;
if (prev == NULL || next == NULL)
{
s->next = s->prev = s;
}
else
{
s->next = next;
s->prev = prev;
}
return s;
}
4、双向循环链表的插入
static void Insert(ElemType value, pCycDouList list, CycNode* p)
{
CycNode *s = BuyNode(value, p, p->next);
p->next->prev = s;
p->next = s;
list->count++;
}
void InsertCycDouList(pCycDouList list, ElemType value, int pos) //插入函数
{
assert(list != NULL);
if (list->head == NULL)
{
CycNode *s = BuyNode(value, NULL, NULL);
list->head = s;
list->count++;
return;
}
if (pos < 0 || pos > list->count)
{
printf("insert pos is error\n");
return;
}
CycNode *p = list->head;
if (pos == 0)
{
p = p->prev;
Insert(value, list, p);
list->head = list->head->prev;
}
else
{
while (pos > 1)
{
p = p->next;
pos--;
}
Insert(value, list, p);
}
}
5、双向循环链表的删除
void DeleteCycDouList(pCycDouList list, int pos) //删除函数
{
assert(list != NULL);
if (pos < 1 || pos > list->count)
{
printf("delete pos is error\n");
return;
}
if (list->head->next == list->head)
{
free(list->head);
list->head = NULL;
list->count--;
return;
}
CycNode *p = list->head;
if (pos == 1)
{
while (p->next != list->head)
{
p = p->next;
}
list->head = list->head->next;
}
else
{
while (pos > 2)
{
p = p->next;
pos--;
}
}
CycNode *q = p->next;
p->next = q->next;
free(q);
list->count--;
}
6、双向循环链表的打印
void ShowCycDouList(pCycDouList list) //打印函数及链表的长度
{
assert(list != NULL);
if (list->head == NULL)
{
printf("list is empty\n");
return;
}
CycNode *p = list->head;
while (p->next != list->head)
{
printf("%d ", p->data);
p = p->next;
}
printf("%d \n", p->data);
printf("len = %d\n", list->count);
}
7、双向循环链表的查找
void FindCycDouList(pCycDouList list,int n) //查找函数
{
assert(list != NULL);
if (n < 0 || n > list->count)
{
printf("count is error\n");
return;
}
CycNode *p = list->head;
for (int i = 1; i < n; i++)
{
p = p->next;
}
printf("%d\n",p->data);
}