---------------start reading---------------
前言
在知道熟悉单链表的操作后,我们知道链表有一个数据域存放具体的数据,有一个next域存放后继的地址,如果我们将尾结点的next域指向之前的任意一个节点,那么就形成了一个环。
下面我们就来说说循环链表
如图就是一个循环链表
在对循环链表进行操作时要注意尾结点的后继不是NULL,而是plist
循环条件要从p->next!=NULL变成p->next!=plist
循环链表可以防止空指针解引用而引起的崩溃,同时也有一定风险会死循环。
下面是循环链表的操作
定义头文件
#pragma once
typedef struct CNode
{
int data;
struct CNode *next;
}CNode,*CList;
//链表初始化
void InitList(CList plist);//Node*
//头插
bool Insert_head(CList plist,int val);
//尾插
bool Insert_tail(CList plist,int val);
//查找
CNode *Srearch(CList plist,int key);
//删除
bool Delete(CList plist,int key);
//获取长度
int GetLength(CList plist);
bool IsEmpty(CList plist);
//清空数据
void Clear(CList plist);
//摧毁
void Destroy(CList plist);
//显示
void Show(CList plist);
循环链表的实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "clist.h"
//带头节点的循环链表
//链表初始化
void InitList(CList plist)
{
assert(plist != NULL);
if(plist==NULL)
{
return ;
}
plist->next = plist;//plist->next = NULL;
}
//头插
bool Insert_head(CList plist,int val)
{
CNode *p = (CNode *)malloc(sizeof(CNode));
p->data = val;
p->next = plist->next;
plist->next = p;
return true;
}
//尾插
bool Insert_tail(CList plist,int val)
{
CNode *p = (CNode *)malloc(sizeof(CNode ));
p->data = val;
CNode *q;
for(q=plist;q->next!=plist;q=q->next) ;//循环条件改变
//将p插入在q的后面
p->next = q->next;//p->next = plist;
q->next = p;
return true;
}
//查找
CNode *Srearch(CList plist,int key)
{
for(CNode *p=plist->next;p!=plist;p=p->next)
{
if(p->data == key)
{
return p;
}
}
return NULL;
}
//查找前驱
static CNode *SearchPri(CList plist,int key)
{
for(CNode *p=plist;p->next!=plist;p=p->next)
{
if(p->next->data == key)
{
return p;
}
}
return NULL;
}
//删除
bool Delete(CList plist,int key)
{
CNode *p = SearchPri(plist,key);
if(p == NULL)
{
return false;
}
CNode *q = p->next;
p->next = q->next;
free(q);
return true;
}
int GetLength(CList plist)
{
int count = 0;
for(CNode *p=plist->next;p!=plist;p=p->next)
{
count++;
}
return count;
}
bool IsEmpty(CList plist)
{
return plist->next == plist;
}
void Clear(CList plist)
{
Destroy(plist);
}
void Destroy(CList plist)
{
CNode *p;
while(plist->next != plist)//while(!IsEmpty(plist))
{
p = plist->next;
plist->next = p->next;
free(p);
}
}
void Show(CList plist)
{
for(CNode *p=plist->next;p!=plist;p=p->next)
{
printf("%d ",p->data);
}
printf("\n");
}