双向链表-C语言实现结构体双向链表

文章目录

说明

双向链表作为链表数据结构的一种,使用广泛且方便,特别是在操作系统内核的任务调度中。
用C语言实现一般的双向链表比较简单。如下:

typedef struct LIST{
	struct LIST	*next;
	struct LIST	*previous;
    int32_t Data;
} LIST;

inline void ListInit(LIST *list_head)
{
	list_head->next = list_head;
	list_head->previous = list_head;
}

inline void List_BehindInsert(LIST *head, LIST *element)
{//insert after head
	
    element->previous = head;
    element->next = head->next;

    head->next->previous = element;
	head->next = element;
}

inline void List_ForeInsert(LIST *head, LIST *element)
{//insert before head
	
    element->previous = head->previous;
    element->next = head;

    head->previous->next = element;
	head->previous = element;
}

inline void list_delete(LIST *element)
{

	element->previous->next = element->next;
	element->next->previous = element->previous;
	
}

我们分析发现,这种链表每个节点会存储前节点地址、后节点地址、当前节点数据。因此这样构造出的双向链表只能用来存放int32_t类型数据,如果我们想存放float类型数据,就需要重新定义结构体为:

typedef struct LIST{
	struct LIST	*next;
	struct LIST	*previous;
    float Data;
} LIST;

并且无法在一个链表中同时存放float数据和int32_t数据,比如第一个节点存放int32_t,第二个节点存放float,第三个节点存放结构体…

实现

因此,可以采用下面代码来实现指向结构体的链表,或者说是可以存放不同数据的链表:

#define ListEntry(Node, Type, Member)    ((Type *)((uint8_t *)(Node) - (uint32_t)(&((Type *)0)->Member)))
//上面宏定义功能:根据结构体中存在的链表节点的地址找到链表节点所在的结构体
typedef struct LIST
{
	struct LIST	*next;
	struct LIST	*previous;
} LIST;
inline void list_init(LIST *list_head)
{
	list_head->next = list_head;
	list_head->previous = list_head;
}
inline void List_BehindInsert(LIST *head, LIST *element)
{//insert after head
	
    element->previous = head;
    element->next = head->next;

    head->next->previous = element;
	head->next = element;
}

inline void List_ForeInsert(LIST *head, LIST *element)
{//insert before head
	
    element->previous = head->previous;
    element->next = head;

    head->previous->next = element;
	head->previous = element;
}

inline void list_delete(LIST *element)
{

	element->previous->next = element->next;
	element->next->previous = element->previous;
	
}
typedef struct 
{
	int16_t temp1;
    LIST MyList;
}Point_INT16;

typedef struct 
{
	float temp1;
    LIST MyList;
}Point_float;
void main(void)
{
    Point_INT16 FirstNode;
    Point_float SecondNode;
    LIST StartPoint;

    FirstNode.temp1 = 520;
    SecondNode.temp1 = 521.1314000;
    cout.precision(7);

    list_init(&StartPoint);
    List_BehindInsert(&StartPoint,&SecondNode.MyList);
    List_BehindInsert(&StartPoint,&FirstNode.MyList);
    cout<<"第一个节点内容"<<ListEntry(StartPoint.next,Point_INT16,MyList)->temp1<<endl;
    cout<<"第二个节点内容"<<ListEntry(StartPoint.next->next,Point_float,MyList)->temp1<<endl;
    cout<<"循环3个节点内容"<<ListEntry(StartPoint.next->next->next->next,Point_INT16,MyList)->temp1<<endl;
    cout<<"循环4个节点内容"<<ListEntry(StartPoint.next->next->next->next->next,Point_float,MyList)->temp1<<endl;
}

执行结果如下:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天城寺电子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值