企业链表代码实现

本文介绍了Linux内核风格的企业链表的概念,强调了用户需要为元素分配空间并传递指针给链表。通过示例展示了如何定义包含链表节点的结构体,并提供了链表的插入、查找、删除、遍历和释放等操作的C语言实现。此外,还给出了一个用于打印Person结构体实例的示例和一个比较函数。
摘要由CSDN通过智能技术生成

目录

一、企业链表基本概念

二、企业链表代码实现


一、企业链表基本概念

企业链表属于linux内核链表,在单向链表中,当用户插入一个新元素时,单向链表会为存储这个元素的结点malloc新的空间;而在企业链表中,用户需要为自己的元素开辟空间,然后把这个空间的地址通过接口传递给企业链表,企业链表通过void*来作为形参接收

主要依据:由于指针访问数据并不是根据变量名,而是根据偏移量

Linknode包含了链表节点首地址的信息,也含有*next信息;使用时将其转成Linknode * 类型将指针域串起来,代码如下:


//链表小节点
typedef struct LinkNode
{
    struct LinkNode* next;

}LinkNode;

//链表节点
typedef struct LINKLIST
{
    LinkNode head;//不是指针,而是一个LinkNode结构体
    int size;

}Linklist;

当使用时,将Linknode*数据转换为自己的Person*数据,定义首地址相同的结构体,即可根据偏移量访问到数据

typedef struct Person
{
    LinkNode node;
    char name[20];
    int age;

}Person;

//打印 遍历函数
void myPrint(LinkNode* data){
    Person *p = (Person*)data;
    std::cout << "Name:" << p->name << " Age:" << p->age << std::endl;
}

二、企业链表代码实现

Linklist.h

//author:kdf
//title:企业链表
//time:2022/3/23
#ifndef LINKLIST_H_INCLUDED
#define LINKLIST_H_INCLUDED

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


//链表小节点
typedef struct LinkNode
{
    struct LinkNode* next;

}LinkNode;

//链表节点
typedef struct LINKLIST
{
    LinkNode head;//不是指针,而是一个LinkNode结构体
    int size;

}Linklist;

//遍历函数指针  制造回调函数
typedef void(*PRINTNODE)(LinkNode*);

//比较函数指针
typedef int(*COMPARE)(LinkNode*,LinkNode*);

Linklist* Init_Linklist();//初始化
//插入
void Insert_Linklist(Linklist* list,int pos,LinkNode* data);
//查找
int Find_Linklist(Linklist* list,LinkNode* data,COMPARE compare);
//删除
void Remove_Linklist(Linklist* list,int pos);
//返回链表大小
int Size_Linklist(Linklist* list);
//打印
void Print_Linklist(Linklist* list,PRINTNODE print);
void Free_Linklist(Linklist* list);//释放

#endif // LINKLIST_H_INCLUDED

Linklist.cpp

//author:kdf
//title:企业链表
//time:2022/3/23

#include "Linklist.h"

Linklist* Init_Linklist()//初始化
{
    Linklist* list=( Linklist* )malloc(sizeof( Linklist));
    list->head.next=NULL;
    list->size=0;
    return list;

}
//插入
void Insert_Linklist(Linklist* list,int pos,LinkNode* data)
{
    if(list==NULL)
    {
        return;

    }
    if(data==NULL)
    {
        return;
    }
    if(pos<0 || pos>list->size)
    {
        return;
    }
    //查找插入位置
   LinkNode* pCurrent=&(list->head);

 //  LinkNode* pCurrent=list->head.next;错误
    for(int i=0;i<pos;i++)
    {
        pCurrent=pCurrent->next;
    }
    //插入新节点
    data->next=pCurrent->next;
    pCurrent->next=data;

    list->size++;
}

//查找
int Find_Linklist(Linklist* list,LinkNode* data,COMPARE compare)
{
    if(list==NULL)
    {
        return -1;
    }
    if(data==NULL)
    {
        return -1;
    }
    //辅助指针变量
     LinkNode* pCurrent=list->head.next ;
    int pos=0;
    int flag=-1;
    while(pCurrent!=NULL)
    {
        if(compare(pCurrent,data)==0)
        {
            flag=pos;
            break;
        }
        pCurrent=pCurrent->next;
        pos++;
    }

     return flag;//可能出现查不到的情况


}
//删除
void Remove_Linklist(Linklist* list,int pos)
{
     if(list==NULL)
    {
        return;
    }
     if(pos<0 || pos>list->size)
    {
        return;
    }
    LinkNode* pCurrent=&(list->head) ;//指针指向地址
    for(int i=0;i<pos;i++)
    {
        pCurrent=pCurrent->next;
    }
    pCurrent->next=pCurrent->next->next;
    list->size--;


}
//返回链表大小
int Size_Linklist(Linklist* list)
{
    return list->size;
}
//打印
void Print_Linklist(Linklist* list,PRINTNODE print)
{
    if(list==NULL)
    {
        return;
    }
     LinkNode* pCurrent=list->head.next;
     while(pCurrent!=NULL)
     {
         print(pCurrent);
         pCurrent=pCurrent->next;
     }
}
void Free_Linklist(Linklist* list)//释放
{
     if(list==NULL)
    {
        return;
    }
    free(list);
    list=NULL;
    printf("free Linklist!\n");
}

main.cpp

//author:kdf
//title:企业链表
//time:2022/3/23

#include <iostream>
#include "Linklist.h"
using namespace std;


typedef struct Person
{
    LinkNode node;
    char name[20];
    int age;

}Person;

//打印 遍历函数
void myPrint(LinkNode* data){
    Person *p = (Person*)data;
    std::cout << "Name:" << p->name << " Age:" << p->age << std::endl;
}


//比较函数
int mycompare(LinkNode* data1,LinkNode* data2)
{

    Person* d1=(Person*)data1;
    Person* d2=(Person*)data2;
    if((strcmp(d1->name,d2->name)==0)&&d1->age==d2->age)
    {
        return 0;
    }

        return -1;


}

int main()
{


    //创建链表
	Linklist* list=Init_Linklist();
	Person m1,m2,m3,m4,m5;
	strcpy(m1.name,"aaa");
	strcpy(m2.name,"bbb");
	strcpy(m3.name,"ccc");
	strcpy(m4.name,"ddd");
	strcpy(m5.name,"eee");
	m1.age=10;
	m2.age=20;
	m3.age=30;
	m4.age=40;
	m5.age=50;

	//插入节点
	Insert_Linklist(list,0,(LinkNode*)&m1);
	Insert_Linklist(list,0,(LinkNode*)&m2);
	Insert_Linklist(list,0,(LinkNode*)&m3);
	Insert_Linklist(list,0,(LinkNode*)&m4);
	Insert_Linklist(list,0,(LinkNode*)&m5);

	Print_Linklist(list,myPrint);


	//删除节点
	Remove_Linklist(list,2);
	cout<<"--------------------------"<<endl;
	Print_Linklist(list,myPrint);


	//查找
	Person findP;
	strcpy(findP.name,"eee");
	findP.age=50;
	int pos=Find_Linklist(list,(LinkNode*)(&findP),mycompare);
	cout<<pos<<endl;

	//销毁
	Free_Linklist(list);

    cout << "Hello world!" << endl;
    return 0;
}

 

注:本文为记录学习过程中遇到的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值