04黑马数据结构笔记之(双向)循环企业链表(小挂钩)

04黑马数据结构笔记之(双向)循环企业链表(小挂钩)

1 思路:循环企业链表几乎与企业链表一样。何为循环,就是使链表的尾部不指向NULL,而指向链表的开头,即指向头结点,clist->head.next=&(clist->head); //使链表尾部指向头结点–循环。

同样以一个结构体管理链表,链表内使用挂钩连接存储数据。

//挂钩结构体
typedef struct CSNode{
	struct CSNode *next;
}CircleSNode;

//管理链表结构体
typedef struct CList{
	CircleSNode head;
	int size;
}CircleList;

代码实现:
1)头文件.h:

#ifndef CIRCLELIST_H
#define CIRCLELIST_H

//挂钩结构体
typedef struct CSNode{
	struct CSNode *next;
}CircleSNode;

//管理链表结构体
typedef struct CList{
	CircleSNode head;
	int size;
}CircleList;

//查找回调函数
typedef int (*MYCOMPAER)(CircleSNode *c1,CircleSNode *c2);
//打印回调函数
typedef void (*PRINT)(CircleSNode *c);

//链表初始化
CircleList *Init_CircleList();
//插入链表
int Insert_CircleList(CircleList *clist,int pos,CircleSNode *data);
//删除 -根据位置
int DelByPos_CircleList(CircleList *clist,int pos);
//删除 -根据值
int DelByValue_CircleList(CircleList *clist,CircleSNode *data,MYCOMPAER comp);
//查找
int Find_CircleList(CircleList *clist,CircleSNode *data,MYCOMPAER comp);
//打印
int Print_CircleList(CircleList *clist,PRINT print);
//获取第一个元素
CircleSNode *GetFront_CircleList(CircleList *clist);
//返回链表大小
int GetSize_CircleList(CircleList *clist);
//销毁内存
int Destory_CircleList(CircleList *clist);
#endif

2).cpp文件:

#include"CircleList.h"
#include<stdio.h>
#include<stdlib.h>

//链表初始化
CircleList *Init_CircleList(){

	CircleList *clist=(CircleList*)malloc(sizeof(CircleList));
	clist->head.next=&(clist->head); //使链表尾部指向头结点--循环
	clist->size=0;

	return clist;

}
//插入链表
int Insert_CircleList(CircleList *clist,int pos,CircleSNode *data){

	if(clist==NULL){
		return -1;
	}
	//数据为空也没必要插入
	if(data==NULL){
		return -1;
	}
	if(pos<0 || pos>clist->size){
		pos=clist->size;
	}
	    //插入
	//先找到要插入前一节点
	CircleSNode *pPre=&(clist->head);
	for(int i=0;i<pos;i++){
		pPre=pPre->next;
	}
	//开始插入
	data->next=pPre->next;
	pPre->next=data;

	clist->size++;

	return 0;

}
//删除 -根据位置
int DelByPos_CircleList(CircleList *clist,int pos){

	if(clist==NULL){
		return -1;
	}
	if(pos<0||pos>=clist->size){
		printf("输入下标有误,数组越界了!\n");
		return -1;
	}
	    //删除
	//找到要删除点的前一节点
	CircleSNode *pPre=&(clist->head);
	for(int i=0;i<pos;i++){
		pPre=pPre->next;
	}
	//开始删除
	pPre->next=pPre->next->next;

	clist->size--;

	return 0;
}
//删除 -根据值
int DelByValue_CircleList(CircleList *clist,CircleSNode *data,MYCOMPAER comp){

	if(clist==NULL){
		return -1;
	}
	if(data==NULL){
		return -1;
	}
/*  while删除
	int i=0;
	CircleSNode *pPre=&(clist->head);
	CircleSNode *pCur=clist->head.next;
	while(pCur!=&(clist->head)){
		if(comp(pCur,data)){
			break;
		}
		pPre=pCur;
		pCur=pCur->next;
		i++;
	}
	//如果找到i肯定会少加一次1
	if(i==clist->size){
		printf("没有找到可删除的值\n");
		return -1;
	}
	//开始删除
	pPre->next=pCur->next;
*/
	//for删除
	CircleSNode *pPre=&(clist->head);
	CircleSNode *pCur=clist->head.next;
	for(int i=0;i<clist->size;i++){
		if(comp(pCur,data)){
			break;
		}
		pPre=pCur;
		pCur=pCur->next;
	}

	//开始删除
	pPre->next=pCur->next;

	clist->size--;

	return 0;

}
//查找
int Find_CircleList(CircleList *clist,CircleSNode *data,MYCOMPAER comp){
	if(clist==NULL){
		return -1;
	}
	if(data==NULL){
		return -1;
	}
	int i=0;
	CircleSNode *pCur=clist->head.next;
	while(pCur!=&(clist->head)){
		if(comp(pCur,data)){
			break;
		}
		pCur=pCur->next;
		i++;
	}
	//如果找到i肯定会少加一次1
	if(i==clist->size){
		printf("没有找到可删除的值\n");
		return -1;
	}

	return i;
}
//打印
int Print_CircleList(CircleList *clist,PRINT print)  {

	if(clist==NULL){
		return -1;
	}
/*
	CircleSNode *pCur=clist->head.next;
	while(pCur!=&(clist->head)){

		print(pCur);
		pCur=pCur->next;
	}
*/
	CircleSNode *pCur=clist->head.next;
	for(int i=0;i<clist->size;i++){
		//多次打印,在打印之前,跳过头结点
		if(pCur==&(clist->head)){
			pCur=pCur->next;
		}
		print(pCur);
		pCur=pCur->next;
	}
	return 0;
}
//获取第一个元素
CircleSNode *GetFront_CircleList(CircleList *clist){
	return clist->head.next;
}
//返回链表大小
int GetSize_CircleList(CircleList *clist){
	return clist->size;
}
//销毁内存
int Destory_CircleList(CircleList *clist){

	if(clist==NULL){
		return -1;
	}
	free(clist);

	return 0;
}

3)主函数测试:

#include"CircleList.h"
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//自定义类型
typedef struct Per{
	CircleSNode node;  //每个自定义类型都使用挂钩串联
	char name[64];
	int age;
}Person;

//打印回调函数
void MyPrint(CircleSNode *cs){
	Person *p=(Person *)cs;
	printf("名字:%s 年龄:%d\n",p->name,p->age);

}

//比较回调函数
int MyCompare(CircleSNode *cs1,CircleSNode *cs2){
	Person *p1=(Person *)cs1;
	Person *p2=(Person *)cs2;
	if(strcmp(p1->name,p2->name)==0 &&p1->age==p2->age){
		return 1;
	}
	return 0;
}

void test01(){

	//创建链表
	CircleList *clist=Init_CircleList();

	//创建数据
	Person p1,p2,p3,p4,p5;
	strcpy(p1.name,"aaa");
	strcpy(p2.name,"bbb");
	strcpy(p3.name,"ccc");
	strcpy(p4.name,"ddd");
	strcpy(p5.name,"eee");

	p1.age=20;
	p2.age=18;
	p3.age=16;
	p4.age=66;
	p5.age=22;

	//插入数据
	Insert_CircleList(clist,1000,(CircleSNode*)&p1);
	Insert_CircleList(clist,1000,(CircleSNode*)&p2);
	Insert_CircleList(clist,1000,(CircleSNode*)&p3);
	Insert_CircleList(clist,1000,(CircleSNode*)&p4);
	Insert_CircleList(clist,1000,(CircleSNode*)&p5);
	//打印数据
	Print_CircleList(clist,MyPrint);

	//查找
	printf("==========\n");
	int pos = Find_CircleList(clist,(CircleSNode*)&p3,MyCompare);
	printf("查找的数据下标为:%d\n",pos);

	printf("==========\n");
	//删除数据
	DelByPos_CircleList(clist,2);
	Print_CircleList(clist,MyPrint);
	printf("==========\n");
	DelByValue_CircleList(clist,(CircleSNode*)&p4,MyCompare);
	Print_CircleList(clist,MyPrint);



	//销毁内存
	Destory_CircleList(clist);

}

int main(){

	test01();

	return 0;
}

总结循环链表:使尾节点不指向空,指向头结点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值