单向循环链表简单实现
头文件:CircleLinkList.h
#ifndef CIRCLELINKLIST_H //防止头文件被重复调用
#define CIRCLELINKLIST_H
#define CIRCLE_TRUE 1
#define CIRCLE_FALSE 0
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//链表内部小节点
typedef struct CIRCLELINNODE {
struct CIRCLELINKNODE* next;
}CircleLinkNode;
//链表结构体
typedef struct CICLELINKLIST {
CircleLinkNode head; //这里如果是指针变量的话,就需要在初始化时为其分配内存空间,结束时还要释放,所以不使用其指针
int size;
}CircleLinkList;
//比较函数的回调
typedef int(*COMPARENODE_2)(CircleLinkNode*, CircleLinkNode*);
//打印函数的回调
typedef void(*PRINTNODE)(CircleLinkNode*);
//编写针对链表结构体操作的函数
//初始化函数
CircleLinkList* INIT_CIRCLELINKLIST();
//插入函数
void Insert_CircleLinkList(CircleLinkList* list, int pos, CircleLinkNode* data);
//获得第一个元素、
CircleLinkNode* Front_CircleLinkList(CircleLinkList* list);
//删除操作
void RemoveByPos_CircleLinkList(CircleLinkList* list, int pos); //按位置删除
//根据值删除
void RemoveByVal_CircleLinkList(CircleLinkList* list, CircleLinkNode* data ,COMPARENODE_2) ;
//获得链表长度
int Size_CircleLinkList(CircleLinkList* list);
//查找
int Find_CircleLinkList(CircleLinkList* list, CircleLinkNode* data, COMPARENODE_2);
//打印节点,参数num表示打印遍数
void Print_CircleLinkList(CircleLinkList* list,PRINTNODE print,int num);
//默认只打印一次
void Print_CircleLinkList_Once(CircleLinkList* list, PRINTNODE print);
//释放内存
void FreeSpace_CircleLinkList(CircleLinkList* list);
#endif CIRCLELINKLIST_H
实现文件:CircleLinkList.c
#include"CircleLinkList.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//初始化函数
CircleLinkList* INIT_CIRCLELINKLIST() {
CircleLinkList* list = (CircleLinkList*)malloc(sizeof(CircleLinkList));
list->head.next = &(list->head); //循环链表,所以尾部重新指回头部
list->size = 0;
return list;
}
//插入函数
void Insert_CircleLinkList(CircleLinkList* list, int pos, CircleLinkNode* data) {
if (list == NULL) {
return;
}
if (data == NULL) {
return;
}
if (pos<0 || pos>list->size) {
pos = list->size;
}
//根据位置获取节点
//定义辅助指针,注意,在操作指针的过程中,尽量不使用原指针,避免对指针变量做出更改
CircleLinkNode* pCurrent = &(list->head);
for (int i = 0; i < pos;i++) {
pCurrent = pCurrent->next;
}
//将数据插入链表
data->next = pCurrent->next;
pCurrent->next = data;
list->size++;
}
//获得第一个元素、
CircleLinkNode* Front_CircleLinkList(CircleLinkList* list) {
return list->head.next;
}
//删除操作
void RemoveByPos_CircleLinkList(CircleLinkList* list, int pos) {
//按位置删除
if (list == NULL) {
return;
}
if (pos<0 || pos>=list->size) {
return;
}
//根据pos找节点
CircleLinkNode* pCurrent = &(list->head);
for (int i = 0; i < pos; i++) {
pCurrent = pCurrent->next;
}
//缓存删除节点的下一个节点
CircleLinkNode* pNext = pCurrent->next;
pCurrent->next = pNext->next;
//由于我们并没有为数据分配内存,所以每个节点的创建与释放都是用户来操作
list->size--;
}
//根据值删除
void RemoveByVal_CircleLinkList(CircleLinkList* list, CircleLinkNode* data, COMPARENODE_2 compare) {
if (list == NULL) {
return;
}
if (data == NULL) {
return;
}
//因为是循环链表,所以不能用尾节点指向NULL作为循环条件
//这里可以利用链表长度进行有限次循环
CircleLinkNode* pPrev = &(list->head); //当前判断值的前一个位置
CircleLinkNode* pCurrent = list->head.next;
for (int i = 0; i < list->size; i++) {
if (compare(pCurrent, data) == CIRCLE_TRUE) {
pPrev->next = pCurrent->next;
list->size--;
break;
}
pPrev = pCurrent;
pCurrent = pPrev->next;
}
}
//获得链表长度
int Size_CircleLinkList(CircleLinkList* list){
return list->size;
}
//查找
int Find_CircleLinkList(CircleLinkList* list, CircleLinkNode* data, COMPARENODE_2 compare) {
if (list == NULL) {
return-1;
}
if (data == NULL) {
return-1;
}
CircleLinkNode* pCurrent = list->head.next;
int flag = -1;
for (int i = 0; i < list->size; i++) {
if (compare(pCurrent, data) == CIRCLE_TRUE) {
flag = i;
break;
}
pCurrent = pCurrent->next;
}
return flag;
}
//打印节点
void Print_CircleLinkList(CircleLinkList* list, PRINTNODE print,int num) {
if (list == NULL) {
return-1;
}
CircleLinkNode* pCurrent = list->head.next;
for (int i = 0; i < (list->size)*num; i++) { //循环打印num遍
if (pCurrent == &(list->head)) { //判断是否为头节点,头节点不储存数据所以直接跳过
pCurrent = pCurrent->next;
}
print(pCurrent);
pCurrent = pCurrent->next;
}
}
void Print_CircleLinkList_Once(CircleLinkList* list, PRINTNODE print) {
if (list == NULL) {
return-1;
}
CircleLinkNode* pCurrent = list->head.next;
for (int i = 0; i < (list->size) ; i++) {
print(pCurrent);
pCurrent = pCurrent->next;
}
}
//释放内存
void FreeSpace_CircleLinkList(CircleLinkList* list) {
if (list == NULL) {
return-1;
}
list->size = 0;
free(list);
}
主文件:Main.c
typedef struct PERSON_3 {
CircleLinkNode node;
char name[64];
int age;
}Person_3;
//打印方式
void MyPrint3(CircleLinkNode* data) {
Person_3* p = (Person_3*)data;
printf("姓名:%-10s 年龄:%-10d\n", p->name, p->age);
}
//比较方式
int MyCompare2(CircleLinkNode* pCurrent, CircleLinkNode* data) {
Person_3* p1 = (Person_3*)pCurrent;
Person_3* p2 = (Person_3*)data;
if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age) {
//当姓名年龄都一样时,才返回0
return CIRCLE_TRUE;
}
return CIRCLE_FALSE;
}
void CircleLinkListTest() {
//创建循环链表
CircleLinkList* list = INIT_CIRCLELINKLIST();
Person_3 p1, p2, p3, p4, p5;
strcpy(p1.name, "Tom");
strcpy(p2.name, "Bob");
strcpy(p3.name, "Lili");
strcpy(p4.name, "Bryan");
strcpy(p5.name, "Hugo");
p1.age = 45;
p2.age = 16;
p3.age = 65;
p4.age = 19;
p5.age = 26;
Insert_CircleLinkList(list, 0, (CircleLinkNode*)&p1);
Insert_CircleLinkList(list, 0, (CircleLinkNode*)&p2);
Insert_CircleLinkList(list, 0, (CircleLinkNode*)&p3);
Insert_CircleLinkList(list, 0, (CircleLinkNode*)&p4);
Insert_CircleLinkList(list, 0, (CircleLinkNode*)&p5);
Print_CircleLinkList(list, MyPrint3, 2); //打印两边链表
printf("----------------------------\n");
//删除元素
RemoveByPos_CircleLinkList(list, 2); //按位置
Person_3 p6;
strcpy(p6.name, "Hugo");
p6.age = 26;
RemoveByVal_CircleLinkList(list,(CircleLinkNode*)&p6,MyCompare2); //按值
Print_CircleLinkList(list, MyPrint3, 1); //打印两边链表
printf("----------------------------\n");
FreeSpace_CircleLinkList(list);
}
int main(){
CircleLinkListTest();
system("pause");
return 0;
}
版权声明:本文为renboyu010214原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。