有了前面Linux内核复用实现栈的基础,使用相同的思想实现队列,也是非常简单的。普通单链表复用实现队列,总会在出队或入队的时候有一个O(n)复杂度的操作,大多数采用增加两个变量,一个head,一个tail来将O(n)降成O(1)。但是在内核链表中,天然的双向循环链表,复用实现队列,无论出队还是入队,都是O(1)时间复杂度。

/* main.c   */

#include <stdio.h>
#include <stdlib.h> #include "queue.h" struct person
{
int age;
struct list_head list;
}; int main(int argc,char **argv)
{
int i;
int num =;
struct person *p;
struct person head;
struct person *pos,*n; queue_creat(&head.list); p = (struct person *)malloc(sizeof(struct person )*num); for (i = ;i < num;i++) {
p->age = i*;
in_queue(&p->list,&head.list);
p++;
}
printf("original==========>\n");
list_for_each_entry_safe(pos,n,&head.list,list) {
printf("age = %d\n",pos->age);
}
printf("size = %d\n",get_queue_size(&head.list));
struct person test;
test.age = ;
printf("out_queue %d\n",get_queue_head(pos,&head.list,list)->age);
out_queue(&head.list);
printf("out_queue %d\n",get_queue_head(pos,&head.list,list)->age);
out_queue(&head.list);
printf("in_queue %d\n",test.age);
in_queue(&test.list,&head.list); printf("current==========>\n");
list_for_each_entry_safe(pos,n,&head.list,list) {
printf("age = %d\n",pos->age);
}
printf("size = %d\n",get_queue_size(&head.list));
printf("all member out_queue\n");
list_for_each_entry_safe(pos,n,&head.list,list) {
out_queue(&head.list);
}
printf("size = %d\n",get_queue_size(&head.list));
if (is_empt_queue(&head.list)) {
printf("is_empt_queue\n");
} return ;
}
/*   queue.c  */

#include "queue.h"

void queue_creat(struct list_head *list)
{
INIT_LIST_HEAD(list);
} void in_queue(struct list_head *new, struct list_head *head)
{
list_add_tail(new,head);
} void out_queue(struct list_head *head)
{
struct list_head *list = head->next; /* 保存链表的最后节点 */ list_del(head->next);/* 头删法 */ INIT_LIST_HEAD(list); /* 重新初始化删除的最后节点,使其指向自身 */ } int get_queue_size(struct list_head *head)
{
struct list_head *pos;
int size = ; if (head == NULL) {
return -;
} list_for_each(pos,head) {
size++;
} return size; } bool is_empt_queue(struct list_head *head)
{
return list_empty(head);
}
/*  queue.h  */

#ifndef _QUEUE_H_
#define _QUEUE_H_ #include <stdbool.h>
#include "list.h" #define get_queue_head(pos, head, member) \
list_entry((head)->next, typeof(*pos), member) void queue_creat(struct list_head *list);
void in_queue(struct list_head *new, struct list_head *head);
void out_queue(struct list_head *entry);
int get_queue_size(struct list_head *head);
bool is_empt_queue(struct list_head *head); #endif /* _QUEUE_H_ */

运行结果:

复用Linux内核链表实现队列,时间复杂可以很简单的实现O(1),当然,其中的遍历队列长度是O(n),不过这个在之前的随笔中也说到了,根据具体的应用场景,可以在入队的时候在头结点中size+1,出队的时候在头结点中size-1,获取队列大小的函数就可以直接返回size了,是可以很轻易做到O(1)的时间复杂度的。掌握了Linux内核链表,链表,栈和队列这样的数据结构,就可以很容易的实现复用,并且可以应用在实际项目中。

最新文章

  1. 无废话WCF入门教程六[一个简单的Demo]
  2. 《UML大战需求分析》阅读笔记4
  3. struts2整合CKEditor和CKFinder实现上传
  4. 1-2+3-4+5-6+7......+n的几种实现
  5. iOS面试题 02
  6. Word Ladder II
  7. Terrible Sets
  8. This manual page is part of Xcode Tools version 5.0
  9. Table表格横竖线实现Css
  10. HTML学习笔记 day two
  11. 吴恩达机器学习笔记58-协同过滤算法(Collaborative Filtering Algorithm)
  12. 源自于NEO的KeyValue 数据库面世啦
  13. 在 Android 的文字编辑控件 (TEdit) 中, 如何按下 Enter 就隐藏虚拟键盘
  14. Asp.Net SignalR - 持久连接类
  15. Java课程2019年3月开学测试
  16. vue实现双向数据绑定之Object.defineProperty()篇
  17. Delphi 解决Utf8ToAnsi和Utf8DeCode转换编码为空的问题
  18. 下载安装mysql的一些坑
  19. 悟空模式-java-建造者模式
  20. excel数据批量导入

热门文章

  1. 马哥docker听课记录
  2. Mac原型动画设计软件Drama创建3D图层的注意事项,你知道吗?
  3. Socket网络编程-IO各种概念及多路复用
  4. 在ubuntu系统中,遇到 “由于/bin 不在PATH 环境变量中,故无法找到该命令”问题
  5. 无法打开jetbrains官网
  6. httprunner学习14-完整的项目结构设计
  7. 追光的人beta冲刺总结
  8. Java的Socket通信简单实例
  9. 论文画图工具使用(2)vision软件
  10. Json断言