当前位置:   article > 正文

C语言——栈与队列的实现_c语言队列和栈的实现

c语言队列和栈的实现

栈与队列都是受限的线性表,均可以通过顺序表(数组)和链表两种方式得到实现。只不过栈是FILO,队列是FIFO,即栈和队列在出和入的方式上有所不同。而通过数组和链表实现的区别,即为数组与链表本身的区别:数组的存储空间是连续的,不可动态扩展;链表的存储空间是不连续的,可以动态扩展。下面具体来说。

一、栈的实现:

栈有栈底和栈顶,栈底是固定的,栈顶指向栈最顶上的第一个数据;数据的入栈和出栈只能在栈顶端进行;故只需为栈指定栈顶即可,栈顶的数据类型决定于栈中数据定位的方式。

1.顺序栈:

顺序栈是以数组的方式实现栈,数组是靠索引定位数据,故顺序栈的栈顶与数组索引的类型一致,为int型;

具体的代码实现:

2.链栈:

链栈是以链表的方式实现栈,链表是靠指针定位数据,故链栈的栈顶与链表指针的类型一致,为链结点的指针;

具体的实现代码:

二、队列的实现:

队列有队首和队尾,在数组队列中,一般大家的做法是:队首指向队列的第一个数据,队尾指向队列最后一个数据的下一个数据;数据的入队只能在队尾进行,数据的出队只能在队首进行;在链队列中,队首指向头结点,队尾指向尾结点;故需分别指定队首和队尾,队首和队尾的数据类型决定于队列中数据定位的方式。

具体的代码实现参考:

队列的存储结构和常见操作(c 语言实现) - dashuai的博客 - 博客园

1.顺序队列:

队首和队尾为int类型,对应数组索引;

一般的顺序队列,若队首的数据出队后,其他数据要到队首需要进行移动,而数组又不便于数据的移动,故采用循环队列。

在循环队列中:

删除数据后,队首=队首+1应修改为:队首=(队首+1)%队列长度;

插入数据后,队尾=队尾+1应修改为:队尾=(队尾+1)%队列长度;

但在循环队列中,队列为空和队列为满时,队首和队尾的指向是相同的,

故需加以区分,区分的方式有:

(1)、另设一个布尔变量以区别队列的空和满;

(2)、少用一个元素的空间,约定入队前测试尾指针在循环下加 1 后是否等于头指针,若相等则认为队满;

(3)、使用一个计数器记录队列中元素的总数。

2.链队列:

队首和队尾对应头指针和尾指针;为了操作的方便,在初始化队列时,可以为队列添加一个头结点,判断队列为空的条件时:队首=队尾,指向头节点;

3.个人思考:

对顺序栈、链栈、链队列,栈首、队首、队尾都指向的是该方向的第一个数据;而在循环队列中,队首指向队列第一个数据,队尾指向队列最后一个数据的下一位;形式上不够统一。

所以我的想法是,能不能对循环队列做一个改进,使之在队首、队尾的概念上能与链队列等达成统一;

经过思考,得到的方案是:重新定义队列为空:

队列为空:队首指向队列的第一个空数据;队尾指向队首-1,即队列的最后一个空数据;

这样一来,队列为满时:队首指向队列的第一个数据;队尾指向队列的最后一个数据;符合队首与队尾的定义。不过,队列为空和队列为满,队首和队尾的指向还是相同,需要加以区分,区分的方式:

(1)、另设一个布尔变量以区别队列的空和满;

(2)、使用一个计数器记录队列中元素的总数。

具体实现的代码:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #define SizeOfQueue 6
  5. typedef struct Queue
  6. {
  7. int data[SizeOfQueue];
  8. int head;
  9. int tail;
  10. int cnt;
  11. }queue;
  12. queue* queue_init()
  13. {
  14. queue* qe = (queue*)malloc(sizeof(queue));
  15. if (NULL == qe)
  16. {
  17. printf("Init queue erroe");
  18. exit(1);
  19. }
  20. memset(qe, 0, sizeof(queue));
  21. qe->head = 0;
  22. qe->tail = SizeOfQueue - 1;
  23. qe->cnt = 0;
  24. return qe;
  25. };
  26. void en_queue(queue* qe,int data1)
  27. {
  28. if (qe->cnt == SizeOfQueue)//判断栈满;
  29. {
  30. printf("Queue is full");
  31. exit(1);
  32. }
  33. qe->tail = (qe->tail+1)%SizeOfQueue;
  34. qe->data[qe->tail] = data1;
  35. qe->cnt += 1;
  36. };
  37. void de_queue(queue* qe)
  38. {
  39. int tmp_data;
  40. if(qe->cnt==0)
  41. {
  42. printf("Queue is empty");
  43. exit(1);
  44. }//判断栈空
  45. tmp_data = qe->data[qe->head];
  46. qe->head = (qe->head + 1) % SizeOfQueue;
  47. qe->cnt -= 1;
  48. };
  49. int main()
  50. {
  51. queue* que;
  52. que = queue_init();
  53. int data[5] = {1,2,3,4,5};
  54. for (int i = 0; i < 5; i++)
  55. {
  56. en_queue(que, data[i]);
  57. }
  58. de_queue(que);
  59. de_queue(que);
  60. en_queue(que, 6);
  61. en_queue(que, 7);
  62. en_queue(que, 8);
  63. en_queue(que, 9);
  64. };

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

闽ICP备14008679号