该循环链表由clist.h +clist.cpp + main.cpp 组成
clist.h文件
#pragma once
//循环链表:尾部节点的next指向头节点,形成一个环;
//带头节点
typedef struct CNode
{
int data;
struct CNode* next;
}CNode,*CList;
//初始化
void InitList(CList plist);
//头插
bool Insert_head(CList plist, int val);
//尾插
bool Insert_tail(CList plist, int val);
//插入数据,在plist链表的pos位置插入val;
bool Insert(CList plist, int pos, int val);
//判空
bool IsEmpty(CList plist);
//获取节点个数
int GetLength(CList plist);
//在plist中查找第一个key值,找到返回地址,没有找到返回NULL;
CNode* Search(CList plist, int key);
//删除pos位置的值
bool DelPos(CList plist, int pos);
//删除第一个val的值
bool DelVal(CList plist, int val);
//返回key的前驱地址,如果不存在返回NULL;
CNode* GetPrio(CList plist, int key);
//返回key的后继地址,如果不存在返回NULL;
CNode* GetNext(CList plist, int key);
//输出
void Show(CList plist);
//清空数据
void Clear(CList plist);
//销毁整个内存
void Destroy(CList plist);
clist.cpp文件
#include <stdio.h>
#include<assert.h>
#include<stdlib.h>
#include "clist.h"
//循环链表
//初始化
void InitList(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
return;
plist->next = plist;//环形
}
//头插
bool Insert_head(CList plist, int val)
{
assert(plist != NULL);
if (plist == NULL)
return false;
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));
assert(p != NULL);
p->data = val;
//找尾巴
CNode* q;
for (q = plist; q->next != plist; q = q->next)
{
;
}
p->next = q->next;//p->next=plist;
q->next = p;
return true;
}
//插入数据,在plist链表的pos位置插入val;
bool Insert(CList plist, int pos, int val)
{
assert(plist != NULL);
if (plist == NULL)
return false;
if (pos<0 || pos>GetLength(plist))
{
return false;
}
CNode* p = (CNode*)malloc(sizeof(CNode));
assert(p != NULL);
p -> data = val;
CNode* q;
int i = 0;
for (q = plist; i < pos; i++, q = q->next)//找到需要插入的位置
{
;
}
//将p插入在q的后面
p->next = q->next;
q->next = p;
return true;
}
//判空
bool IsEmpty(CList plist)
{
assert(plist!= NULL);
if (plist == NULL)
return false;
return plist->next == plist;
}
//获取节点个数
int GetLength(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
return 0;
int count = 0;
for (CNode* p = plist->next; p != plist; p = p->next)
{
count++;
}
return count;
}
//在plist中查找第一个key值,找到返回地址,没有找到返回NULL;
CNode* Search(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
for (CNode* p = plist->next; p != plist; p = p->next)
{
if (p->data == key)
{
return p;
}
}
return NULL;
}
//删除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;
int i=0;
for (p = plist; i < pos; i++, p = p->next)
{
;
}
//q是需要删除的节点
CNode *q = p->next;
p->next = q->next;
free(q);
return true;
}
//删除第一个val的值
bool DelVal(CList plist, int val)
{
CNode* p = GetPrio(plist, val);
if (p == NULL)
return false;
CNode* q = p->next;//q为将要删除的点
p->next = q->next;
free(q);
return true;
}
//返回key的前驱地址,如果不存在返回NULL;
CNode* GetPrio(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
for (CNode *p = plist; p->next != plist; p = p->next)
{
if (p->next->data == key)
{
return p;
}
}
return NULL;
}
//返回key的后继地址,如果不存在返回NULL;
CNode* GetNext(CList plist, int key)
{
assert(plist != NULL);
if (plist == NULL)
return NULL;
CNode* p = Search(plist, key);
if (p == NULL)
return NULL;
return p->next;
}
//输出
void Show(CList plist)
{
assert(plist != NULL);
if (plist == NULL)
return;
for (CNode* p = plist->next; p != plist; p = p->next)
{
printf("%d ", p->data);
}
printf("\n");
}
//清空数据
void Clear(CList plist)
{
Destroy(plist);
}
//销毁整个内存
void Destroy(CList plist)
{
//总是删除第一个数据节点
CNode* p;
while (plist->next != plist)
{
p = plist->next;
plist->next = p->next;
free(p);
}
}
main文件//测试
#include<stdio.h>
#include<assert.h>
#include<malloc.h>
#include"clist.h"
//链表中最常用的两种循环
//for(p=plist;p->next!=NULL;p=p->next);//需要前驱信息,例如插入,删除等
//for(p=plist->next;p!=NULL;p=p->next);//遍历数据节点,例如,长度,Show,查找等
int main()
{
CNode head;
InitList(&head);
for (int i = 0; i < 10; i++)
{
Insert_tail(&head, i);
}
Show(&head);
Destroy(&head);
Show(&head);
return 0;
}