双向链表-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;
}

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

猜你喜欢

转载自blog.csdn.net/wcc243588569/article/details/117755881