企业链表

本文介绍了企业链表的设计,其灵感来源于Linux内核链表。链表节点仅存储`list_node*`地址,通过将`&Person`转换为`list_node*`来连接节点,并在需要时再转换回`Person*`以访问Person结构体。文中提供了`kernel_list.h`、`kernel_list.c`和`main.c`的实例代码。

企业链表(类似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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值