概述
这个结构体 LinkNode ;
一个结构体占用的字节数是 4 个字节
code
#include "LinkList.h"
/**
* 1. 首先定义数据类型,内部包含了 LinkNode 小挂钩(内部存放下一个节点地址) 和 数据域(内部存放name 和 age)
* 定义其对象P1
* 2. 使用一个LinkNode指针来指向 该对象 P1 地址且进行强制转换为 LinkNode 类型
* (指针赋值相互操作的机制,因为是 指针类型是 LinkNode 类型, 而Person 第一个数据也是该类型
* 所以使用该指针可以访问到第一快内存,若想访问到下面几个数据,需要手动计算需要跳过的字节数,获得其地址来进行访问)
* 3. 插入的时候,只需要插入的 LinkNode 指针,也就是数据对象的地址就可以了
* 相当于把地址串起来,使用的时候,获得该地址,再将其强转获得数据即可。
*/
typedef struct PERSON{
LinkNode node; // 小挂钩 相等于一个next
char name[64];
int age;
}Person;
void test01();
void test02();
void test03();
void Myprint(LinkNode*);
int Mycompare(LinkNode*, LinkNode*);
int main(int argc, char**argv){
test03();
return 0;
}
void test01(){
// 创建 一个链表
LinkList* list = Init_LinkList();
// 创建数据
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;
// 将节点插入到列表
Insert_LinkList(list, 0, (LinkNode*)&P1); // 这个data只能访问到 Person 中的 LinkNode 变量
Insert_LinkList(list, 0, (LinkNode*)&P2);
Insert_LinkList(list, 0, (LinkNode*)&P3);
Insert_LinkList(list, 0, (LinkNode*)&P4);
Insert_LinkList(list, 0, (LinkNode*)&P5);
// 打印
Print_LinkList(list, Myprint);
// 释放内存
FreeSpace_LinkList(list);
}
void test02(){
// 创建 一个链表
LinkList* list = Init_LinkList();
// 创建数据
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;
// 将节点插入到列表
Insert_LinkList(list, 0, (LinkNode*)&P1); // 这个data只能访问到 Person 中的 LinkNode 变量
Insert_LinkList(list, 0, (LinkNode*)&P2);
Insert_LinkList(list, 0, (LinkNode*)&P3);
Insert_LinkList(list, 0, (LinkNode*)&P4);
Insert_LinkList(list, 0, (LinkNode*)&P5);
// 打印
Print_LinkList(list, Myprint);
// 删除节点
RemoveByPos_LinkList(list, 2);
// 打印
Print_LinkList(list, Myprint);
// 释放内存
FreeSpace_LinkList(list);
}
void test03(){
// 创建 一个链表
LinkList* list = Init_LinkList();
// 创建数据
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;
// 将节点插入到列表
Insert_LinkList(list, 0, (LinkNode*)&P1); // 这个data只能访问到 Person 中的 LinkNode 变量
Insert_LinkList(list, 0, (LinkNode*)&P2);
Insert_LinkList(list, 0, (LinkNode*)&P3);
Insert_LinkList(list, 0, (LinkNode*)&P4);
Insert_LinkList(list, 0, (LinkNode*)&P5);
// 打印
Print_LinkList(list, Myprint);
// 查找
Person findP;
strcpy(findP.name, "ccc");
findP.age = 30;
printf("pos = %d\n", Find_LinkList(list, (LinkNode*)&findP, Mycompare));
// 释放内存
FreeSpace_LinkList(list);
}
void Myprint(LinkNode* data){
// 1. 将数据类型再次转回来
Person* p = (Person*)data;
// 2. 打印数据
printf("Name: %s\t Age: %d\n", p->name, p->age);
}
int Mycompare(LinkNode* node1, LinkNode* node2){
// 1. 将数据类型再次转回来
Person* p1 = (Person*)node1;
Person* p2 = (Person*)node2;
// 2. 判断
if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age){
return 0;
}
return -1;
}
#include "LinkList.h"
// 1. 初始化链表
LinkList* Init_LinkList(){
// 这个时候头结点就不需要分配内存L
LinkList* list = (LinkList*)malloc(sizeof(LinkList));
list->head.next = NULL;
list->size = 0;
return list;
}
// 2. 插入 需要注意,这里插入的是 LinkNode* 类型的数据
void Insert_LinkList(LinkList* list, int pos, LinkNode* data){
// 2-1 判定参数的有效性
if(list == NULL){
return;
}
if(data == NULL){
return;
}
// 插入末尾
if(pos < 0 || pos > list->size){
pos = list->size;
}
// 2-2 插入节点
// 2-2-1 查找插入位置
LinkNode* pCurrent = &(list->head);
for(int i = 0; i < pos; i++){
pCurrent = pCurrent->next;
}
// 2-2-2 插入新节点 串接的是地址域
data->next = pCurrent->next;
pCurrent->next = data;
list->size++;
}
// 3. 删除
void RemoveByPos_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;
}
// 删除内存:注意这里 插入的linkNode的时候并没有使用malloc来分配内存,所以释放内存的时候不需要使用free
pCurrent->next = pCurrent->next->next;
list->size--;
}
// 4. 返回链表大小
int Size_LinkList(LinkList* list){
return 0;
}
// 5. 打印
void Print_LinkList(LinkList* list, PRINTFNODE print){
if(list == NULL){
return;
}
LinkNode* pCurrent = list->head.next; // 第一个有效值
while(pCurrent != NULL){
print(pCurrent);
pCurrent = pCurrent->next;
}
printf("---------------------------------\n");
}
// 6. 释放内存空间
void FreeSpace_LinkList(LinkList* list){
if(list == NULL){
return;
}
free(list);
}
// 7. 查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare){
if(list == NULL){
return -1;
}
if(data == NULL){
return -1;
}
// 定义辅助变量,因为是需要查找,所以辅助变量初始化为头结点的next位置
LinkNode* pCurrent = list->head.next;
int index = 0;
int flag = -1;
while (pCurrent != NULL)
{
// 找到逻辑的判断
// 需要一个比较的函数指针和遍历的函数指针
if(compare(pCurrent, data) == 0) // 相等返回0
{
flag = index;
break;
}
// 遍历下一个
pCurrent = pCurrent->next;
index++; // 遍历是从第0开始
}
return flag;
}
#ifndef LINK_LIST_H
#define LINK_LIST_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 链表小节点
typedef struct LINKNODE{
struct LINKNODE* next;
}LinkNode;
// 链表节点
typedef struct LINKLIST
{
LinkNode head;
int size;
}LinkList;
// 定义一个函数指针
typedef void(*PRINTFNODE)(LinkNode*);
// 定义一个比较的函数类型
typedef int(*COMPARENODE)(LinkNode*, LinkNode*);
// 1. 初始化链表
LinkList* Init_LinkList();
// 2. 插入 需要注意,这里插入的是 LinkNode* 类型的数据
void Insert_LinkList(LinkList* list, int pos, LinkNode* data);
// 3. 删除
void RemoveByPos_LinkList(LinkList* list, int pos);
// 4. 返回链表大小
int Size_LinkList(LinkList* list);
// 5. 打印
void Print_LinkList(LinkList* list, PRINTFNODE print);
// 6. 释放内存空间
void FreeSpace_LinkList(LinkList* list);
// 7. 查找
int Find_LinkList(LinkList* list, LinkNode* data, COMPARENODE compare);
#endif
# commands
gcc -fPIC -shared LinkList.c -o liblinkList1.so
gcc main.c -o main -L ./ -llinkList1 -Wl,-rpath ./