博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个通用纯C队列的实现
阅读量:4097 次
发布时间:2019-05-25

本文共 1846 字,大约阅读时间需要 6 分钟。

队列并不是很复杂的数据结构,但是非常实用,这里实现一个队列是因为在我的另一篇博客中要用到。

 

队列API定义如下:

 

 
  1. //queue.h

  2.  
  3. #ifndef QUEUE_H_INCLUDED

  4. #define QUEUE_H_INCLUDED

  5.  
  6. typedef struct queue *queue_t;

  7.  
  8. queue_t queue_create();

  9.  
  10. int queue_isempty(queue_t q);

  11.  
  12. void* queue_enqueue(queue_t q, unsigned int bytes);

  13.  
  14. void* queue_dequeue(queue_t q);

  15.  
  16. void queue_destroy(queue_t q);

  17.  
  18. #endif //QUEUE_H_INCLUDED

队列API提供的功能有:创建队列,判断队列是否为空,入队,出队,销毁队列。这个队列是通用的,不针对特定数据类型,它里面存储的元素是void*类型的指针。注意这个队列跟普通队列的入队操作有所不同。普通队列的入队操作通常如下:

 

 
  1. struct type *p;

  2. p = malloc(sizeof(struct type));

  3. p->a = ...;

  4. p->b = ...;

  5. p->c = ...;

  6. ...

  7. queue_enqueue(q, p);

而这里的入队操作简化了流程:

 

 
  1. struct type *p;

  2. p=queue_enqueue(q, sizeof(struct type));

  3. p->a = ...;

  4. p->b = ...;

  5. p->c = ...;

  6. ...

另外虽然队列元素(指针)所指向的内存空间是在入队操作时由队列分配的,但是队列元素出队以后,队列并不负责元素所指向内存空间的释放,队列使用者应该自己手动释放内存。

 

队列的实现如下:

 

 
  1. //queue.c

  2.  
  3. #include "queue.h"

  4. #include <stdlib.h>

  5.  
  6. struct node {

  7. void *element;

  8. struct node *next;

  9. };

  10.  
  11. struct queue {

  12. struct node front;

  13. struct node *tail;

  14. };

  15.  
  16. queue_t queue_create() {

  17. queue_t q;

  18. q=(queue_t)malloc(sizeof(struct queue));

  19. q->front.element=NULL;

  20. q->front.next=NULL;

  21. q->tail=&q->front;

  22. return q;

  23. }

  24.  
  25. int queue_isempty(queue_t q) {

  26. return &q->front==q->tail;

  27. }

  28.  
  29. void* queue_enqueue(queue_t q, unsigned int bytes) {

  30. q->tail->next=(struct node*)malloc(sizeof(struct node));

  31. q->tail->next->element=malloc(bytes);

  32. q->tail->next->next=NULL;

  33. q->tail=q->tail->next;

  34. return q->tail->element;

  35. }

  36.  
  37. void* queue_dequeue(queue_t q) {

  38. struct node *tmp=q->front.next;

  39. void *element;

  40. if(tmp==NULL) {

  41. return NULL;

  42. }

  43. element=tmp->element;

  44. q->front.next=tmp->next;

  45. free(tmp);

  46. if(q->front.next==NULL) {

  47. q->tail=&q->front;

  48. }

  49. return element;

  50. }

  51.  
  52. void queue_destroy(queue_t q) {

  53. struct node *tmp, *p=q->front.next;

  54. while(p!=NULL) {

  55. tmp=p;

  56. p=p->next;

  57. free(tmp);

  58. }

  59. free(q); // 感谢@Toudsour指正

  60. }

应用程序使用队列时只需要包含queue.h头文件,并在编译时将queue.c一起编译就行了。因为队列的声明和实现是严格分离的,包含queue.h的应用程序无法也不应该通过队列指针直接访问队列结构体的成员。

转载地址:http://dwlii.baihongyu.com/

你可能感兴趣的文章
沙雕程序员在无聊的时候,都搞出了哪些好玩的小玩意...
查看>>
太赞了!GitHub 标星 2.4k+,《可解释机器学习》中文版正式开放!
查看>>
程序员用 AI 修复百年前的老北京视频后,火了!
查看>>
漫话:为什么你下载小电影的时候进度总是卡在 99% 就不动了?
查看>>
我去!原来大神都是这样玩转「多线程与高并发」的...
查看>>
当你无聊时,可以玩玩 GitHub 上这个开源项目...
查看>>
B 站爆红的数学视频,竟是用这个 Python 开源项目做的!
查看>>
安利 10 个让你爽到爆的 IDEA 必备插件!
查看>>
自学编程的八大误区!克服它!
查看>>
GitHub 上的一个开源项目,可快速生成一款属于自己的手写字体!
查看>>
早知道这些免费 API,我就可以不用到处爬数据了!
查看>>
Java各种集合类的合并(数组、List、Set、Map)
查看>>
JS中各种数组遍历方式的性能对比
查看>>
Mysql复制表以及复制数据库
查看>>
进程管理(一)
查看>>
linux 内核—进程的地址空间(1)
查看>>
存储器管理(二)
查看>>
开局一张图,学一学项目管理神器Maven!
查看>>
Android中的Binder(二)
查看>>
Framework之View的工作原理(一)
查看>>