LinkList.h
#pragma once
#ifndef __COMPANY_LINKLIST_H
#define __COMPANY_LINKLIST_H
#include<stdlib.h>
#include<stdio.h>
//链表小节点
typedef struct LINKNODE
{
struct LinkNode* next;
}LinkNode;
//链表节点
typedef struct LINKList
{
//实例化一个节点 将其设为头部 且他的nex永远指向 链表的第一个元素
LinkNode head;
int size;
}LinkList;
//声明一个遍历 函数指针
typedef void(*PRINTNODE)(LinkNode*);
//比较函数指针
typedef int(*COMPARENODE)(LinkNode*, LinkNode*);
//初始化链表
LinkList* Init_LinkList();
//根据下标 插入 参1链表 参2下标 参3小节点
void Insert_LinkList(LinkList* list, int pos, LinkNode* data);
//删除
void Remove_LinkList(LinkList* list, int pos);
//查找 根据值返回下标
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare);
//返回链表 大小
int Size_LinkList(LinkList* list);
//打印
void Print_LinkList(LinkList* list, PRINTNODE print);
//释放链表内存
void FreeSpace_LinkList(LinkList* list);
#endif // !LINKLIST_H
03 企业链表.c
#include"LinkList.h"
//自定义数据类型
typedef struct PERSON
{
LinkNode node;
char name[64];//64个字节
int age;//姓名
}Person;
//打印函数 //因为函数名是内存首地址 所以传递的 print=MyPrint
void MyPrint(LinkNode* data)
{
//构造一个类型的 指针指向真实内存,上传的数据地址,框小了,转成大框
//LinkNode*转成Person* 此时框柱了完整数据的 内存
Person* p = (Person*)data;
//格式说明由“%”和格式字符组成,如%d%f等。它的作用是将输出的数据转换为指定的格式输出。格式说明总是由“%”字符开始的。不同类型的数据用不同的格式字符。
printf("Name:%s Age:%d\n", p->name, p->age);
}
int MyCompare(LinkNode*nodel1, LinkNode* nodel2)
{
Person* p1 = (Person*)nodel1;
Person* p2 = (Person*)nodel2;
if (strcmp(p1->name, p2->name) == 0 && p1->age == p2->age)
{
return 0;
}
return -1;
}
int main() {
//创建链表 Init_LinkList() 此函数才是开辟内存,并且将内存用指针返回
LinkList* lisit = Init_LinkList();
printf("size:%d\n",sizeof(lisit));
//创建数据类型
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 = 10;
p2.age = 20;
p3.age = 30;
p4.age = 40;
p5.age = 50;
//数据入链表
//位置选0类似头插,全插在脑袋上
//先传入p1类型的指针,但是p1指针指向的内存大了,转成LinkNode*的指针,将框变小,
//类似p1里有节点钩子(LinkNode node;)这个p1的钩子会钩住p2的钩子
Insert_LinkList(lisit, 0, (LinkNode*)&p1);
Insert_LinkList(lisit, 0, (LinkNode*)&p2);
Insert_LinkList(lisit, 0, (LinkNode*)&p3);
Insert_LinkList(lisit, 0, (LinkNode*)&p4);
Insert_LinkList(lisit, 0, (LinkNode*)&p5);
//打印 //因为函数名是内存首地址 所以传递的 print=MyPrint
//甚至此时用 引用的方式也可以传值 下面用指针可以,
// 因为本质上就是传递 函数的首地址
Print_LinkList(lisit, MyPrint);
printf("--------------------------------------\n");
//删除 根据下标删除
Remove_LinkList(lisit, 0);
Print_LinkList(lisit, MyPrint);
printf("--------------------------------------\n");
//查找
Person findP;
strcpy(findP.name, "ccc");
findP.age = 30;
int pos=Find_LinkList(lisit, (LinkNode*)&findP, MyCompare);
printf("位置:%d\n", pos);
////返回第一个节点 如果是是空链表 这里很危险 目前我还不知道怎么解决
//Person* ret = (Person*)Front_LinkList(lisit);
//printf("retName:%s retAge:%d retScore:%d\n", ret->name, ret->age);
//printf("--------------------------------------\n");
//销毁链表
FreeSpace_LinkList(lisit);
printf("\n");
system("pause");
return 0;
}
LinkList.c
#include"LinkList.h"
//初始化链表
LinkList* Init_LinkList()
{
LinkList* list = (LinkList*)malloc(sizeof(LinkList));
list->head.next = NULL;
list->size = 0;
return list;
}
//根据下标 插入 参1链表 参2下标 参3小节点
void Insert_LinkList(LinkList* list, int pos, LinkNode* data)
{
if (list == NULL)
{
return-1;
}
if (data == NULL)
{
return-1;
}
if (pos<0 || pos>list->size)
{
pos = list->size;
}
//查找插入位置
LinkNode* pCurrent = &(list->head);
for (int i = 0; i < pos; i++)
{
pCurrent = pCurrent->next;
}
//插入新节点
data->next = pCurrent->next;
pCurrent->next = data;
list->size++;
}
//删除
void Remove_LinkList(LinkList* list, int pos)
{
if (list == NULL)
{
return-1;
}
if (pos<0 || pos>=list->size)
{
return-1;
}
LinkNode* pCurrent = &list->head;
for (int i = 0; i < pos; i++)
{
pCurrent = pCurrent->next;
}
pCurrent->next = pCurrent->next->next;
list->size--;
}
//查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare)
{
if (list == NULL)
{
return -1;
}
if (data == NULL)
{
return-1;
}
LinkNode* pCurrent = list->head.next;
int index = 0;
int flag = -1;
while (pCurrent!=NULL)
{
if (compare(pCurrent, data) == 0)
{
flag = index;
break;
}
pCurrent = pCurrent->next;
index++;
}
return flag;
}
//返回链表 大小
int Size_LinkList(LinkList* list)
{
return 0;
}
//打印
void Print_LinkList(LinkList* list, PRINTNODE print)
{
if (list == NULL)
{
return-1;
}
//辅助指针
LinkNode* pCurnent = list->head.next;
while (pCurnent!=NULL)
{
print(pCurnent);
pCurnent = pCurnent->next;
}
}
//释放链表内存
void FreeSpace_LinkList(LinkList* list)
{
if (list == NULL)
{
return-1;
}
free(list);
}