数据结构一:链表(循环链表)

一:实现机制

Linux链表实现思想就是:结点里面只创建一个next指针,用指针将各个结点相连接 打印和查找的时候,再进行类型的转换。
循环链表在Linux链表的基础上改动,最后结点的next指向的是开始头结点,而Linux链表最后结点的next指向的是NULL;循环链表在在初始化时,头结点指向它本身(clist->head.next=&(clist->head);)
在这里插入图片描述

二:代码

1 CircleLinkList.h

/*
CircleLinkList.h
实现机制为linux链表(企业链表) 
*/
#ifndef  _CIRCLELINKLIST_H_
#define _CIRCLELINKLIST_H_
#include <stdio.h>
#include <stdlib.h>

#define CIRCLELINKLIST_TRUE 0
#define CIRCLELINKLIST_FALSE -1

//创建小节点
typedef struct CIRCLELINKNODE{
	struct CIRCLELINKNODE *next;
}CircleLinkNode; 

//链表 
typedef struct CIRCLELINKLIST{
	CircleLinkNode head;//head头结点,是结构体 
	int size;//链表数据个数 
}CircleLinkList; 

//值删除回调函数 
typedef int (*COMPARE)(CircleLinkNode *data1,CircleLinkNode *data2); 

//打印回调函数
typedef void (*PRINT)(CircleLinkNode *data);

//初始化
CircleLinkList *_Init_List();
//插入
void _Insert_List(CircleLinkList *clist,int pos,CircleLinkNode *data);
//按照位置删除
void _DeleteByPos_List(CircleLinkList *clist,int pos);
//按照值删除
void _DeleteByValue_List(CircleLinkList *clist,CircleLinkNode *data,COMPARE my_Compare);
//返回第一个数据
CircleLinkNode *_Front_List(CircleLinkList *clist);
//获得链表长度
int _Size_List(CircleLinkList *clist);
//打印
void _Print_List(CircleLinkList *clist,PRINT my_Print);
//查找
int _Find_List(CircleLinkList *clist,CircleLinkNode *data,COMPARE my_Compare);
//释放内存
void _Free_List(CircleLinkList *clist);
#endif
 

2 CircleLinkList.c

/*
CircleLinkList.c
*/
#include "CircleLinkList.h"


//初始化
CircleLinkList *_Init_List(){
	CircleLinkList *clist=(CircleLinkList *)malloc(sizeof(CircleLinkList));
	clist->head.next=&(clist->head);
	clist->size=0;
	return clist;
}
//插入
void _Insert_List(CircleLinkList *clist,int pos,CircleLinkNode *data){
	if(clist==NULL){
		return ;
	}
	if(pos<0||pos>clist->size){
		pos=clist->size;//默认往尾部插 
	}
	CircleLinkNode *pCurrent=&(clist->head);
	for(int i=0;i<pos;i++){//寻找前一结点 
		pCurrent=pCurrent->next; 
		
	}
	//插入数据
	data->next=pCurrent->next;
	pCurrent->next=data;
	clist->size++;
}

//打印
void _Print_List(CircleLinkList *clist,PRINT my_Print){
	if(clist==NULL){
		return ;
	}
	CircleLinkNode *pCurrent=(clist->head.next);
	for(int i=0;i<clist->size;i++){
		if(pCurrent==&(clist->head)){//如果打印多次,跳过头指针 
			pCurrent=pCurrent->next; 
		}
		//打印
		my_Print(pCurrent);
		pCurrent=pCurrent->next; 
	}
}
//按照位置删除
void _DeleteByPos_List(CircleLinkList *clist,int pos){
	if(clist==NULL){
		return ;
	}
	if(pos<0||pos>=clist->size){
		return ;
	}
	CircleLinkNode *pCurrent=&(clist->head);
	for(int i=0;i<pos;i++){//寻找前一结点 
		pCurrent=pCurrent->next; 
	}
	//将这个要删除结点缓存
	CircleLinkNode *DelNode= pCurrent->next;
	pCurrent->next=DelNode->next;
	//释放删除结点空间,
	/*
	if(DelNode!=NULL){
		free(DelNode);
		DelNode=NULL;
	} 
	*/
	
	clist->size--;
}
//按照值删除
void _DeleteByValue_List(CircleLinkList *clist,CircleLinkNode *data,COMPARE my_Compare){
	if(clist==NULL){
		return ;
	}
	if(data==NULL){
		return ;
	}
	CircleLinkNode *PreCurrent= &(clist->head);//数据的前一个 
	CircleLinkNode *pCurrent=PreCurrent->next;//查找到相对应的数据 
	for(int i=0;i<clist->size;i++){
		if(my_Compare(pCurrent,data)==CIRCLELINKLIST_TRUE){//匹配成功 
			PreCurrent->next=pCurrent->next;
			clist->size--;
			break;
		}
		//没有匹配到,定义前后指针注意
		//PreCurrent->next= pCurrent;
		//pCurrent->next=PreCurrent->next; 
		PreCurrent=pCurrent;
		pCurrent=PreCurrent->next;
	}
	
}
//返回第一个数据
CircleLinkNode *_Front_List(CircleLinkList *clist){
	return clist->head.next;
}
//获得链表长度
int _Size_List(CircleLinkList *clist){
	return clist->size;
}
//查找
int _Find_List(CircleLinkList *clist,CircleLinkNode *data,COMPARE my_Compare){
	if(clist==NULL){
		return -1;
	}
	if(data==NULL){
		return -1;
	}
	CircleLinkNode *pCurrent=(clist->head.next);
	int pos=-1;
	for(int i=0;i<clist->size;i++){
		if(my_Compare(pCurrent,data)==CIRCLELINKLIST_TRUE){//找到了 
			pos=i;
			break;
		}
		pCurrent=pCurrent->next;
	}
	return pos;
}
//释放内存
void _Free_List(CircleLinkList *clist){
	if(clist!=NULL){
		free(clist);
		clist=NULL;
	}
}

3 main.c

/*
main.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CircleLinkList.h"

typedef struct PERSON{
	CircleLinkNode node;
	char name[64];
	int age;
}Person;

//打印回调
void my_Print(CircleLinkNode *data){
	Person *p=(Person*)data;
	printf("name:%s  age:%d\n",p->name,p->age);
} 

//比较回调
int my_Compare(CircleLinkNode *data1,CircleLinkNode *data2){
	Person *p1=(Person*)data1;
	Person *p2=(Person*)data2;
	//判断
	if(strcmp(p1->name,p2->name)==CIRCLELINKLIST_TRUE&&p1->age==p2->age) {
		return CIRCLELINKLIST_TRUE;
	}
	else{
		return CIRCLELINKLIST_FALSE;
	}
} 
int main(void){	
	//初始化
	CircleLinkList *clist=_Init_List();
	//创建数据
	Person p1,p2,p3,p4;
	strcpy(p1.name,"AAA"); 
	strcpy(p2.name,"BBB"); 
	strcpy(p3.name,"CCC"); 
	strcpy(p4.name,"DDD"); 
	p1.age=20; 
	p2.age=30;
	p3.age=40;
	p4.age=50;
	
	//插入
	_Insert_List(clist,0,(CircleLinkNode*)&p1);
	_Insert_List(clist,1,(CircleLinkNode*)&p2);
	_Insert_List(clist,2,(CircleLinkNode*)&p3);
	_Insert_List(clist,3,(CircleLinkNode*)&p4);
	//打印
	_Print_List(clist,my_Print);
	
	//查找
	Person p6;
	strcpy(p6.name,"BBB"); 
	p6.age=60;
	int pos=_Find_List(clist,(CircleLinkNode*)&p6,my_Compare);//p6换为p2就可以找到 
	if(pos==-1){
		printf("p2 not found\n");
	}
	else{
		printf("p2 found pos=%d\n",pos);
	}
	//按照值删除
	printf("*********value delete***********\n");
	_DeleteByValue_List(clist,(CircleLinkNode*)&p2,my_Compare);
	_Print_List(clist,my_Print);
	
	//按照位置删除
	printf("*********pos delete***********\n");
	_DeleteByPos_List(clist,1);
	_Print_List(clist,my_Print);
	printf("List length:%d\n",_Size_List(clist));
	
	//释放内存
	 _Free_List(clist);
	
	return 0;
}

三:结果显示

1.编译环境

centos 3.10.0-862.el7.x86_64 
gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)

2.编译命令

gcc main.c CircleLinkList.c -std=c99
./a.out

3.结果显示
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

唐维康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值