[C语言]STL-单向循环链表简单实现

单向循环链表简单实现

头文件: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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值