queue.h之tailq.h尾队列理解使用

一、连接、组织方式

如图:
  • 每个entry有两个关键元素:tqe_next(简称为next)、tqe_prev(简称为prev)。next指向下个entry的地址,prev指向上个entry的next的地址。
next容易理解。对于prev,说白了prev的值就是上个 entry的next的地址。这样说可能还有点模糊,再换种说法prev的值为上个entry的地址加上next的偏移量。
画个图理解下:
所以,可以通过prev的值,改变上一个entry的next值(插入、删除),当然也可以获得、改变上一个entry的prev值(获得上上个entry的next。。。)。因此可以通过prev向先遍历、向后遍历,也可以通过next向前遍历,向后遍历。注意:next和prev是地址相邻的,属于一个不可变的结构体。
一个尾队列的连接结构如图所示:

二、使用步骤

1、定义队列类

这里可以用对象化的思想去理解尾队列。
1、定义entry,加入data
struct tail_ql_entry 
{
	TAILQ_ENTRY(tail_ql_entry) next;
	int data;
};
2、定义head,定义队列类
TAILQ_HEAD(tail_list,tail_ql_entry);

2、实例化一个队列(对象化)

struct tail_list list1;
当然想实例化多少个都行,以后tail_list就相当于一个自定义数据类型(队列、链表)。

3、操作对象

例如在队列头插入一个entry
	struct tail_ql_entry * elm1 = malloc(sizeof(struct tail_ql_entry));
	elm1->data = 0;
	TAILQ_INSERT_HEAD(&list1,elm1,next);
其他的方法见queue.h。

三、实例

1、代码

#include 
#include 

#include 

struct tail_ql_entry 
{
	TAILQ_ENTRY(tail_ql_entry) next;
	int data;
};

TAILQ_HEAD(tail_list,tail_ql_entry);

struct tail_list list1;

int main()
{

	TAILQ_INIT(&list1);
	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");

	struct tail_ql_entry * elm1 = malloc(sizeof(struct tail_ql_entry));
	elm1->data = 0;
	TAILQ_INSERT_HEAD(&list1,elm1,next);

	struct tail_ql_entry * elm2 = malloc(sizeof(struct tail_ql_entry));
	elm2->data = 1;
	TAILQ_INSERT_AFTER(&list1,elm1,elm2,next);

	struct tail_ql_entry *var = NULL;
	TAILQ_FOREACH(var,&list1,next)
	{
		printf("foreach:%d\n",var->data);
	}

	TAILQ_FOREACH_REVERSE(var,&list1,tail_list,next)
	{
		printf("foreach_reverse:%d\n",var->data);
	}

	printf("elm1 next=%d\n",TAILQ_NEXT(elm1,next)->data);

	printf("elm2 pre=%d\n",TAILQ_PREV(elm2,tail_list,next)->data);

	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");

	TAILQ_REMOVE(&list1,elm1,next);
	free(elm1);
	TAILQ_REMOVE(&list1,elm2,next);
	free(elm2);
	
	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");
	
	return 0;
	
	

#include 

#include 

struct tail_ql_entry 
{
	TAILQ_ENTRY(tail_ql_entry) next;
	int data;
};

TAILQ_HEAD(tail_list,tail_ql_entry);

struct tail_list list1;

int main()
{

	TAILQ_INIT(&list1);
	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");

	struct tail_ql_entry * elm1 = malloc(sizeof(struct tail_ql_entry));
	elm1->data = 0;
	TAILQ_INSERT_HEAD(&list1,elm1,next);

	struct tail_ql_entry * elm2 = malloc(sizeof(struct tail_ql_entry));
	elm2->data = 1;
	TAILQ_INSERT_AFTER(&list1,elm1,elm2,next);

	struct tail_ql_entry *var = NULL;
	TAILQ_FOREACH(var,&list1,next)
	{
		printf("foreach:%d\n",var->data);
	}

	TAILQ_FOREACH_REVERSE(var,&list1,tail_list,next)
	{
		printf("foreach_reverse:%d\n",var->data);
	}

	printf("elm1 next=%d\n",TAILQ_NEXT(elm1,next)->data);

	printf("elm2 pre=%d\n",TAILQ_PREV(elm2,tail_list,next)->data);

	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");

	TAILQ_REMOVE(&list1,elm1,next);
	free(elm1);
	TAILQ_REMOVE(&list1,elm2,next);
	free(elm2);
	
	printf("list1 is empty? %s.\n",TAILQ_EMPTY(&list1)? "YES":"NO");
	
	return 0;
	
	

2、运行结果

如图:
  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值