一个通用纯C队列的实现

https://blog.csdn.net/kxcfzyk/article/details/31728179

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

队列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的应用程序无法也不应该通过队列指针直接访问队列结构体的成员。

猜你喜欢

转载自blog.csdn.net/sinat_35297665/article/details/81177313