企业链表(类似linux内核链表)

- 链表只连接 list_node ,其中存放是list_node* 地址
- 将(list_node*)&Person ,这样只能访问 list_node成员 next ,也就是Person的第一个成员
- head里面存 (list_node*)&Person ,然后将下一个Person首地址赋值给当前的 next
- 需要Person的时候,在强转(Person*)回来
实例代码
kernel_list.h
#ifndef __KERNEL_LIST_H
#define __KERNEL_LIST_H
#include <stdio.h>
#include <stdlib.h>
typedef struct LISTNODE
{
struct LISTNODE* next;
}List_Node;
typedef struct LIST_INFO
{
List_Node* head;
List_Node* tail;
int size;
}List_Info;
typedef int (*COMPARE_LIST)(List_Node*,List_Node*);
typedef void (*PRINT) (List_Node* );
List_Info* Init_List(void);
void Push_back(List_Info* list, List_Node* data);
void Insert_List(List_Info* list, int pos, List_Node* data);
void Remove_List(List_Info* list, int pos);
int Find_List(List_Info* list, List_Node* data, COMPARE_LIST compare_list);
void Print_List(List_Info* list, PRINT print);
#endif
kernel_list.c
#include "../include/kernel_list.h"
List_Info* Init_List(void)
{
List_Info* list =(List_Info*) malloc(sizeof(List_Info));
list->head = NULL;
list->tail = NULL;
list->size =0;
return list;
}
void Push_back(List_Info* list, List_Node* data)
{
if(list->head == NULL && list->tail == NULL)
{
list->head = data;
list->tail = data;
}
else
{
list->tail->next = data;
list->tail = data;
}
list->size++;
}
void Insert_List(List_Info* list, int pos, List_Node* data)
{
if(pos<0)return;
if(pos>list->size) pos=list->size;
if(pos==0)
{
data->next = list->head;
list->head = data;
}
else
{
List_Node* pCurrent = list->head;
for(int i=0; i<pos-1; i++)
{
pCurrent = pCurrent->next;
}
data->next = pCurrent->next;
pCurrent->next = data;
if(pCurrent == list->tail)
list->tail = data;
}
list->size++;
}
void Remove_List(List_Info* list, int pos)
{
if(pos<0 )return;
if(pos>list->size) pos = list->size;
if(pos==0)//删除第一个
{
list->head = list->head->next;
}
else if(pos==list->size)//删除最后一个
{
List_Node* pCurrent = list->head;
while(--pos)
{
list->tail=pCurrent;
pCurrent->next=NULL;
}
pCurrent=pCurrent->next;
}
}
else//删除中间
{
List_Node* pCurrent = list->head;
while(--pos)
{
pCurrent = pCurrent->next;
}
pCurrent->next = pCurrent->next->next;
}
list->size--;
}
int Find_List(List_Info* list, List_Node* data, COMPARE_LIST compare_list)
{
List_Node* pCurrent = list->head;
int i=0;
for(i=0; i<list->size; i++)
{
if(compare_list(pCurrent,data))
{
break;
}
pCurrent = pCurrent->next;
}
return i;
}
void Print_List(List_Info* list, PRINT print)
{
List_Node* pCurrent = list->head;
for(int i=0; i<list->size; i++)
{
print(pCurrent);
pCurrent = pCurrent->next;
}
}
main.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../include/kernel_list.h"
typedef struct PERSON
{
List_Node* node;
char name[64];
int id;
}Person;
void print(List_Node* data)
{
Person* p = (Person*) data;
printf("name: %s, id: %d\n",p->name,p->id);
}
int compare_list(List_Node* data1, List_Node* data2)
{
Person* p1 =(Person*)data1;
Person* p2 =(Person*)data2;
if(p1->name == p2->name && p1->id == p2->id)
return 1;
else
return 0;
}
int main(void)
{
List_Info* list = Init_List();
Person p1,p2,p3,p4,p5;
strcpy(p1.name, "julian");
strcpy(p2.name, "candy");
strcpy(p3.name, "juju");
strcpy(p4.name, "mike");
strcpy(p5.name, "kerr");
p1.id=1;
p2.id=2;
p3.id=3;
p4.id=4;
p5.id=5;
Push_back(list,(List_Node*)&p1);
Push_back(list,(List_Node*)&p2);
Push_back(list,(List_Node*)&p3);
Push_back(list,(List_Node*)&p4);
Push_back(list,(List_Node*)&p5);
Print_List(list,print);
printf("------查找candy---------\n");
int tmp=Find_List(list,(List_Node*)&p2,compare_list);
printf("pos: %d\n",tmp);
printf("---------2位置插入fuck--------\n");
printf("---------0位置插入silly--------\n");
printf("---------tial位置插入doubi--------\n");
Person p6,p7,p8;
strcpy(p6.name,"fuck");
strcpy(p7.name,"silly");
strcpy(p8.name,"doubi");
p6.id=6;
p7.id=7;
p8.id=8;
Insert_List(list,2,(List_Node*)&p6);
Insert_List(list,0,(List_Node*)&p7);
Insert_List(list,7,(List_Node*)&p8);
Print_List(list,print);
printf("----------删除第一个------\n");
Remove_List(list,0);
Print_List(list,print);
printf("----------删除最后一个------\n");
Remove_List(list,7);
Print_List(list,print);
printf("----------删除中间------\n");
Remove_List(list,1);
Print_List(list,print);
return 0;
}
结果:
name: julian, id: 1
name: candy, id: 2
name: juju, id: 3
name: mike, id: 4
name: kerr, id: 5
------查找candy---------
pos: 1
---------2位置插入fuck--------
---------0位置插入silly--------
---------tial位置插入doubi--------
name: silly, id: 7
name: julian, id: 1
name: candy, id: 2
name: fuck, id: 6
name: juju, id: 3
name: mike, id: 4
name: kerr, id: 5
name: doubi, id: 8
----------删除第一个------
name: julian, id: 1
name: candy, id: 2
name: fuck, id: 6
name: juju, id: 3
name: mike, id: 4
name: kerr, id: 5
name: doubi, id: 8
----------删除最后一个------
name: julian, id: 1
name: candy, id: 2
name: fuck, id: 6
name: juju, id: 3
name: mike, id: 4
name: kerr, id: 5
----------删除中间------
name: julian, id: 1
name: fuck, id: 6
name: juju, id: 3
name: mike, id: 4
name: kerr, id: 5
本文介绍了企业链表的设计,其灵感来源于Linux内核链表。链表节点仅存储`list_node*`地址,通过将`&Person`转换为`list_node*`来连接节点,并在需要时再转换回`Person*`以访问Person结构体。文中提供了`kernel_list.h`、`kernel_list.c`和`main.c`的实例代码。
1847

被折叠的 条评论
为什么被折叠?



