当前位置:   article > 正文

c语言之————有头循环双链表实现队列存储_用双向链表作为队列的存储形式c语言

用双向链表作为队列的存储形式c语言

1、链表

dlist.h

  1. /*
  2. *dlist.h
  3. *描述:
  4. * 有头循环双表
  5. *Data:
  6. * 2014-07-21
  7. */
  8. #pragma once
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. struct node_info
  13. {
  14. struct node_info *prev;
  15. struct node_info *next;
  16. char par[]; /*0长数组,不占空间*/
  17. };
  18. struct list_info
  19. {
  20. struct node_info head;
  21. /*
  22. * 头插
  23. */
  24. void (*add)(struct list_info *,size_t data_size,const void *data_entry);
  25. /*
  26. * 尾插
  27. */
  28. void (*add_tail)(struct list_info *,size_t data_size,const void *data_entry);
  29. /*
  30. * 得到第一个数据
  31. */
  32. void (*get)(struct list_info *,size_t data_size,void *data_entry);
  33. /*
  34. * 获得最后一个数据
  35. */
  36. void (*get_tail)(struct list_info *,size_t data_size, void *data_entry);
  37. /*
  38. * 删除节点
  39. */
  40. void (*del)(struct list_info *,struct node_info *);
  41. /*
  42. * 判断节点是否为空
  43. */
  44. int (*isempty)(struct list_info *);
  45. };
  46. void list_init(struct list_info*);
  47. void list_destroy(struct list_info*);
  48. #define PAR(node,type) ((type*)node->par)
  49. #define list_for_each(info, cur) \
  50. for (cur = (info)->head.next; \
  51. (cur) != &(info)->head; \
  52. cur = (cur)->next)
  53. #define list_for_each_safe(info, cur, tmp) \
  54. for (cur = (info)->head.next, tmp = (cur)->next; \
  55. (cur) != &(info)->head; \
  56. cur = tmp, tmp = (tmp)->next)

dlist.c

  1. /*
  2. *dlist.c
  3. *
  4. */
  5. #include "dlist.h"
  6. static void list_add(struct list_info *info,size_t data_size,const void *data_entry)
  7. {
  8. struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info) + data_size);
  9. memcpy(new_node->par,data_entry,data_size);
  10. new_node->prev = &info->head;
  11. new_node->next = info->head.next;
  12. info->head.next = new_node;
  13. new_node->next->prev = new_node;//info->head.next->prev = new_node;
  14. }
  15. static void list_add_tail(struct list_info *info,size_t data_size,const void *data_entry)
  16. {
  17. struct node_info *new_node = (struct node_info *)malloc(sizeof(struct node_info) + data_size);
  18. memcpy(new_node->par,data_entry,data_size);
  19. new_node->prev = info->head.prev;
  20. new_node->next = &info->head;
  21. info->head.prev->next = new_node;
  22. info->head.prev = new_node; //new_node->prev->next = new_node;
  23. }
  24. static void list_get(struct list_info *info,size_t data_size,void *data_entry)
  25. {
  26. memcpy(data_entry, info->head.next->par, data_size);
  27. }
  28. static void list_get_tail(struct list_info *info,size_t data_size,void *data_entry)
  29. {
  30. memcpy(data_entry, info->head.prev->par, data_size);
  31. }
  32. static void list_del(struct list_info *info,struct node_info *node)
  33. {
  34. node->prev->next = node->next;
  35. node->next->prev = node->prev;
  36. node->next = node;
  37. node->prev = node;
  38. free(node);
  39. }
  40. static int list_isempty(struct list_info *info)
  41. {
  42. // return info->head.prev == &info->head;
  43. return info->head.next == &info->head;
  44. }
  45. void list_init(struct list_info *info)
  46. {
  47. info->head.prev = &info->head;
  48. info->head.next = &info->head;
  49. info->add = list_add;
  50. info->add_tail = list_add_tail;
  51. info->get = list_get;
  52. info->get_tail = list_get_tail;
  53. info->del = list_del;
  54. info->isempty = list_isempty;
  55. }
  56. void list_destroy(struct list_info *info)
  57. {
  58. struct node_info *cur = NULL;
  59. struct node_info *tmp = NULL;
  60. list_for_each_safe(info, cur, tmp)
  61. {
  62. info->del(info, cur);
  63. }
  64. }

2、队列

queue.h

  1. /*
  2. * queue.h
  3. *队列原理是先进的先出
  4. */
  5. #pragma once
  6. #include "dlist.h"
  7. struct queue_info
  8. {
  9. struct list_info list;
  10. /*
  11. * 入列
  12. */
  13. void (*push)(struct queue_info *,size_t data_size,const void *data_entry);
  14. /*
  15. * 出列
  16. */
  17. int (*pop)(struct queue_info *,size_t data_size,void *data_entry);
  18. /*
  19. * 队头
  20. */
  21. int (*top)(struct queue_info *,size_t data_size,void *data_entry);
  22. /*
  23. * 判断队列是否为空
  24. */
  25. int (*isempty)(struct queue_info *);
  26. };
  27. struct queue_info *queue_init(struct queue_info *);
  28. void queue_destroy(struct queue_info *);

queue.c

  1. /*
  2. * queue.c
  3. *
  4. */
  5. #include "queue.h"
  6. static void queue_push(struct queue_info *info,size_t data_size,const void *data_entry)
  7. {
  8. info->list.add_tail(&info->list,data_size,data_entry);
  9. }
  10. static int queue_top(struct queue_info *info,size_t data_size,void *data_entry)
  11. {
  12. /*
  13. * 如果队列为空,
  14. */
  15. if(info->isempty(info))
  16. {
  17. return -1;
  18. }
  19. else
  20. {
  21. info->list.get(&info->list,data_size,data_entry);
  22. return 0;
  23. }
  24. }
  25. static int queue_pop(struct queue_info *info,size_t data_size,void *data_entry)
  26. {
  27. /*
  28. * 假如队列头不存在
  29. */
  30. if(info->top(info,data_size,data_entry))
  31. {
  32. return -1;
  33. }
  34. else
  35. {
  36. info->list.del(&info->list,info->list.head.next);
  37. return 0;
  38. }
  39. }
  40. static int queue_isempty(struct queue_info *info)
  41. {
  42. return info->list.isempty(&info->list);
  43. }
  44. struct queue_info *queue_init(struct queue_info *info)
  45. {
  46. list_init(&info->list);
  47. info->push = queue_push;
  48. info->top = queue_top;
  49. info->pop = queue_pop;
  50. info->isempty = queue_isempty;
  51. return info;
  52. }
  53. void queue_destroy(struct queue_info *info)
  54. {
  55. list_destroy(&info->list);
  56. }

3、测试代码

test.c

  1. /*
  2. * test.c
  3. *
  4. */
  5. #include "queue.h"
  6. struct data_info
  7. {
  8. const char*name;
  9. size_t age;
  10. };
  11. int main()
  12. {
  13. struct queue_info queue;
  14. struct data_info s[] = {
  15. {"jack",20},
  16. [1] = {
  17. .name = "marry",
  18. .age = 22
  19. },
  20. [2] = {"peter",21}
  21. };
  22. queue_init(&queue);
  23. size_t i = 0;
  24. for(i = 0; i < sizeof(s)/sizeof(struct data_info);i ++)
  25. {
  26. queue.push(&queue,sizeof(struct data_info),s + i);
  27. }
  28. if(queue.isempty(&queue))
  29. {
  30. printf("queue is empty!\n");
  31. }
  32. else
  33. {
  34. printf("queue is not empty!\n");
  35. }
  36. struct data_info tmp;
  37. if(queue.top(&queue,sizeof(struct data_info),&tmp))
  38. printf("no top data!\n");
  39. else
  40. {
  41. printf("Top data is : name %s , age is %d \n",tmp.name,tmp.age);
  42. }
  43. queue_destroy(&queue);
  44. printf("After destroy stack ... \n");
  45. if(queue.isempty(&queue))
  46. {
  47. printf("queue is empty!\n");
  48. }
  49. else
  50. {
  51. printf("queue is not empty!\n");
  52. }
  53. return 0;
  54. }

4、Makefile

  1. all:test
  2. test:test.o dlist.o queue.o
  3. gcc -o $@ $^
  4. test.o:test.c
  5. gcc -c test.c
  6. dlist.o:dlist.c
  7. gcc -c dlist.c
  8. queue.o:queue.c
  9. gcc -c queue.c
  10. clean:
  11. rm *.o test

5、测试结果

  1. queue is not empty!
  2. Top data is : name jack , age is 20
  3. After destroy stack ...
  4. queue is empty!


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/660797
推荐阅读
相关标签
  

闽ICP备14008679号