企业链表-Linux内核链表优化简单实现

企业链表-Linux内核链表优化简单实现

头文件:LinuxKernelList.h

 1 #ifndef  LINUXKERNELLIST_H
 2 #define LINUXKERNELLIST_H
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 #include<string.h>
 6 
 7 //链表指针节点
 8 typedef struct LINUXNODE {
 9     struct LINUXNODE* next;
10 }LinuxNode;
11 
12 //链表真正节点
13 typedef struct LINUXLIST {
14     LinuxNode head;
15     int size;
16 }LinuxList;
17 
18 //遍历函数的指针
19 typedef void(*PRINTNODE)(LinuxNode*);
20 //比较函数的指针
21 typedef int(*COMPARENODE)(LinuxNode*, LinuxNode*);
22 
23 
24 //初始化链表
25 LinuxList* INIT_LINUXLIST();
26 //插入链表
27 void Insert_LinuxList(LinuxList* list, int pos, LinuxNode* data);
28 //删除链表
29 void Remove_LinuxList(LinuxList* list, int pos);
30 //查找链表元素
31 int Find_LinuxList(LinuxList* list, LinuxNode* data ,COMPARENODE compare);
32 //返回链表大小
33 int Size_LinuxList(LinuxList* list);
34 //打印链表
35 void Print_LinuxList(LinuxList* list, PRINTNODE print);
36 //释放链表内存
37 void FreeSpace_LinuxList(LinuxList* list);
38 
39 
40 #endif // ! LINUXKERNELLIST_H

实现文件:LinuxKernelList.c

 1 #include "LinuxKernelList.h"
 2 
 3 
 4 //初始化链表
 5 LinuxList* INIT_LINUXLIST() {
 6     LinuxList* list = (LinuxList*)malloc(sizeof(LinuxList));
 7     list->head.next = NULL;
 8     list->size = 0;
 9     return list;
10 }
11 //插入链表
12 void Insert_LinuxList(LinuxList* list, int pos, LinuxNode* data) {
13     if (list == NULL) {
14         return;
15     }
16     if (data == NULL) {
17         return;
18     }
19     if (pos<0 || pos>list->size) {
20         pos = list->size;
21     }
22     //查找插入位置
23     LinuxNode* pCurrent = &(list->head);
24     for (int i = 0; i < pos; i++) {
25         pCurrent = pCurrent->next;
26     }
27     //插入新节点
28     data->next = pCurrent->next;
29     pCurrent->next = data;
30     list->size++;
31 }
32 //删除链表
33 void Remove_LinuxList(LinuxList* list, int pos) {
34     if (list == NULL) {
35         return;
36     }
37     if (pos<0 || pos>list->size) {
38         pos = list->size;
39     }
40     //查找删除位置
41     LinuxNode* pCurrent = &(list->head);
42     for (int i = 0; i < pos; i++) {
43         pCurrent = pCurrent->next;
44     }
45     //删除节点
46     pCurrent->next = pCurrent->next->next;
47     //因为我们并没有在节点里分配内存,数据信息储存在链表的其他域内,所以我们在删除时也不需要释放内存
48     list->size--;
49 
50 }
51 //查找链表元素
52 int Find_LinuxList(LinuxList* list, LinuxNode* data, COMPARENODE compare) {
53     if (list == NULL) {
54         return-1;
55     }
56     if (data == NULL) {
57         return-1;
58     }
59     //辅助指针
60     LinuxNode* pCurrent = list->head.next;
61     int index = 0;
62     int flag = -1;  //用于判断是否查找到了目标值
63     //如果查找到了就将index 赋给flag
64     //如果没查找到,就将flag=-1返回
65     while (pCurrent != NULL) {
66         if (compare(pCurrent, data)==0) {
67             flag = index;
68             break;
69         }
70         pCurrent = pCurrent->next;
71         index++;
72     }
73     return flag;
74 }
75 //返回链表大小
76 int Size_LinuxList(LinuxList* list) {
77     return list->size;
78 }
79 //打印链表
80 void Print_LinuxList(LinuxList* list, PRINTNODE print) {
81     if (list == NULL) {
82         return;
83     }
84     //辅助指针
85     LinuxNode* pCurrent = list->head.next;
86     while (pCurrent != NULL) {
87         print(pCurrent);
88         pCurrent = pCurrent->next;
89     }
90 
91 
92 }
93 //释放链表内存
94 void FreeSpace_LinuxList(LinuxList* list) {
95     if (list == NULL) {
96         return;
97     }
98     free(list);
99 }

主文件:Main.c

typedef struct  PERSON_2{
    LinuxNode node;  //加入结构体作为连接多组数据的桥梁
    /*
    这里巧妙之处在于把node放到MyData结构体首地址的位置
    这样在定初始化一个MyData结构体后
    只需要利用强制类型转换就可以获得结构体首地址
    需要利用元素时,只需要将地址强制转换回结构体类型即可
    MyData data1;
    LinuxNode* node=(LinuxNode*) &data1;
    MyData data2=(MyData) node;
    */
    char name[64];
    int age;
}Person_2;

//打印方式
void MyPrint2(LinuxNode*data) {
    Person_2* p = (Person_2*)data;
    printf("姓名:%-10s 年龄:%-10d\n", p->name, p->age);
}

//比较方式
int MyCompare(LinuxNode* pCurrent,LinuxNode*data) {
    Person_2* p1 = (Person_2*)pCurrent;
    Person_2* p2 = (Person_2*)data;
    if (strcmp(p1->name , p2->name)==0 && p1->age==p2->age) { 
        //当姓名年龄都一样时,才返回0
        return 0;
    }
    return -1;

}


void LinuxListTest() {
    /*企业链表操作*/
    //创建链表
    LinkList* list = INIT_LINUXLIST();
    //创建数据
    Person_2 p1, p2, p3, p4, p5;
    strcpy(p1.name, "Tom");
    strcpy(p2.name, "Bob");
    strcpy(p3.name, "Lili");
    strcpy(p4.name, "Bryan");
    strcpy(p5.name, "Hugo");
    p1.age = 45;
    p2.age = 16;
    p3.age = 65;
    p4.age = 19;
    p5.age = 26;
    //将节点插入链表
    Insert_LinuxList(list, 0, (LinuxNode*)&p1);
    Insert_LinuxList(list, 0, (LinuxNode*)&p2);
    Insert_LinuxList(list, 0, (LinuxNode*)&p3);
    Insert_LinuxList(list, 0, (LinuxNode*)&p4);
    Insert_LinuxList(list, 0, (LinuxNode*)&p5);
    //打印链表
    Print_LinuxList(list, MyPrint2);
    //删除节点
    printf("------------------------\n");
    Remove_LinuxList(list, 2);
    Print_LinuxList(list, MyPrint2);
    //查找
    Person_2 p6;
    strcpy(p6.name, "Bob");
    p6.age = 16;
    int index = Find_LinuxList(list, (LinuxNode*)&p6, MyCompare);
    printf("------------------------\n");
    printf("链表中存在这个人,他的索引是:%d\n", index);
    //释放链表内存
    FreeSpace_LinuxList(list);

}

int main(){
    LinuxListTest();
    system("pause");
    return 0;
}

 转自博友https://www.cnblogs.com/renboyu/p/13150247.html

posted @ 2022-06-05 12:00  油腻老张  阅读(45)  评论(0)    收藏  举报