一:实现机制
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.结果显示