循环单链表是单链表的另一种形式,其结构特点链表中最后一个结点的指针域不再是结束标记,而是指向整个链表的第一个结点,从而使链表形成一个环。和单链表相同,循环链表也有带头结点结构和不带头结点结构两种,带头结点的循环单链表实现插入和删除操作较为方便。
循环单链表只是将单链表的尾结点的指针指向头结点,就直接书写代码,有一点需要主要的是在循环单链表中只有头结点时,将头结点的指针域不指向空,而是执行自己。
1、循环单链表的存储结构
typedef int ElemType;
typedef struct CycNode
{
ElemType data;
struct CycNode *next;
}CycNode;
typedef struct CycLinkList
{
CycNode *head;
int count;
}CycLinkList, *pCycLinkList;
2、循环单链表的初始化
void InitCycList(pCycLinkList list)
{
assert(list != NULL);
list->count = 0;
list->head = NULL;
}
3、循环单链表的扩容
static CycNode *BuyNode(ElemType val, CycNode *next)
{
CycNode *s = (CycNode *)malloc(sizeof(CycNode));
assert(s != NULL);
s->data = val;
if (next != NULL)
{
s->next = next;
}
else
{
s->next = s;
}
return s;
}
4、循环单链表的插入
void InsertCycList(pCycLinkList list, ElemType val, int pos)
{
if (list->head == NULL)
{
list->head = BuyNode(val, NULL);
list->count++;
return;
}
if (pos < 0 || pos > list->count)
{
printf("insert pos is error\n");
return;
}
CycNode *p = list->head;
int pos2 = pos != 0 ? pos : list->count;
while (pos2 > 1)
{
p = p->next;
pos2--;
}
CycNode *s = BuyNode(val, p->next);
p->next = s;
if (pos == 0)
{
list->head = s;
}
list->count++;
}
5、循环单链表的删除
void DeleteCycList(pCycLinkList list, int pos)
{
assert(list != NULL && list->head != NULL);
if (list->head->next == list->head)
{
free(list->head);
list->head = NULL;
list->count--;
return;
}
if (pos < 1 || pos > list->count)
{
printf("delete pos is error\n");
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 ShowCycList(pCycLinkList 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);
}