基础操作包括:初始化、求链表长度、头插、尾插、按位置插、判断是否为空、查找、删除、返回前驱后继下标、输出、清空、销毁。
循环链表即尾节点的next指向头形成一个环
它的结构与单链表一样
typedef struct CNode
{
int data;//数据域
struct CNode* next;//后继指针
}CNode, * CList;
初始化
头指向自己。
void InitCList(CList plist)
{
plist->next = plist;
}
求链表长度
最后一个节点的后继为头,从第一个节点开始遍历,每次count++
int GetLength(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
return -1;
CNode* p = plist->next;
int count = 0;
while (p != plist)
{
count++;
p = p->next;
}
return count;
}
插入
头插
bool Insert_head(CList plist, int val)
{
assert(plist != NULL);
if (plist == NULL)
return false;
CNode* p = (CNode*)malloc(sizeof(CNode));
assert(p != NULL);
p->data = val;
p->next = plist->next;
plist->next = p;
return true;
}
尾插
bool Insert_tail(CList plist, int val)
{
assert(plist != NULL);
if (plist == NULL)
return false;
CNode* p = plist;
CNode* q = (CNode*)malloc(sizeof(CNode));
for (int i = 0; i < GetLength(plist); i++)//找到尾
{
p = p->next;
}
q->data = val;
q->next = p->next;
p->next = q;
return true;
}
按位置插
bool Insert(CList plist, int pos, int val)
{
assert(plist != NULL);
if (pos<0 || pos>GetLength(plist))
return false;
CNode* p = (CNode*)malloc(sizeof(CNode));
assert(p != NULL);
CNode* q = (CNode*)malloc(sizeof(CNode));
assert(q != NULL);
p->data = val;
for(int i = 0; i < pos; i++)
{
q = q->next;
}
p->next = q->next;
q->next = p;
return true;
}
判断是否为空
bool IsEmpty(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
{
return false;
}
if (plist->next == plist)
return true;
return false;
}
查找第一个key
返回其下标,没有则返回NULL
CNode* Search(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
CNode* p = plist->next;
while (p != plist)
{
if (p->data == key)
return p;
}
return NULL;
}
删除
删除pos位置的值(pos是下标)
bool DelPos(CList plist, int pos)
{
assert(plist != NULL);
if (plist == NULL)
return false;
if (pos<0 || pos>=GetLength(plist))
return false;
CNode* p = plist;
for (int i = 0; i < pos; i++)
{
p = p->next;
}
CNode* q = p->next;
p->next = q->next;
free(q);
return true;
}
删除第一个val值
bool DelVal(CList plist, int val)
{
assert(plist != NULL);
if (plist == NULL)
return false;
CNode* p;
CNode* q;
p = GetPrio(plist, val);//找到val的前驱下标
if (p == NULL)//注意判断
return false;
q = p->next;
p->next = q->next;
free(q);
return true;
}
返回前驱、后继下标
//返回key的前驱下标,如果不存在返回NULL
CNode* GetPrio(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
CNode* p = plist;
while (p->next != plist)
{
if (p->next->data == key)
return p;
p = p->next;
}
return NULL;
}
//返回key的后继下标,如果不存在返回NULL
CNode* GetNext(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
CNode* p = plist;
while (p->next != plist)
{
if (p->data == key)
return p->next;
}
return NULL;
}
输出
void Show(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
return;
CNode* p = plist->next;
while (p != plist)
{
printf("-%d-", p->data);
p = p->next;
}
printf("\n");
}
清空和销毁内存
//清空
void Clear(CList plist)
{
Destroy(plist);
}
//销毁
void Destroy(CList plist)
{
//总是删除第一个数据的节点
CNode* p;
while (plist->next != NULL)
{
p = plist->next;
plist->next = p->next;
free(p);
}
//头节点是局部变量不用管。
}