FIFO 队列的链表和数组实现

FIFO (First-in, First-out,先进先出)队列:当执行delete操作时删除那些呆在队列中时间最长的元素。

FIFO 队列是这样一个ADT,包含两个基本操作:插入(put)一个新的项、删除(get)一个最早插入的项。

一、FIFO队列的链表实现

FIFO 队列和下堆栈的区别在于新项的插入是在尾部,而不是在头部。因此实现程序要保存一个指向链表最后一个节点的尾指针tail ,因此当Put操作时,将tail 指针指向的next 指向新节点,然后更新tail指针,让它指向那个新的节点。

FIFO_LinkList.cpp
[cpp]  view plain  copy
  1. /************************************************************* 
  2. 功能:先进先出队列的链表形式实现:Init、Put、Get操作 
  3. 说明:  从头部Get,从尾部Put 
  4. 时间: 2015/02/03 
  5. 作者: quinn 
  6. **************************************************************/  
  7. #include<stdio.h>  
  8. #include<malloc.h>  
  9. #include<stdlib.h>  
  10. typedef int Item;  
  11. typedef struct Node Node;  
  12. typedef Node* Queue;  
  13. struct Node //节点结构  
  14. {  
  15.     Item item;  
  16.     Node* next;  
  17. };  
  18. static int maxN = 10;  
  19. static Queue q = NULL;  
  20. static Node* tail = NULL;  
  21.   
  22. //新建一个节点  
  23. Node* NewNode(Item item, Node* Next) // Next为插入的后一节点  
  24. {  
  25.     Node* x = (Node*)malloc(sizeof(*x));//被插入的节点  
  26.     x->item = item;  
  27.     x->next = Next;  
  28.     return x;  
  29. }  
  30.   
  31. //队列初始化  
  32. void QueueInit(int maxN)  
  33. {  
  34.     q =  NULL;  
  35. }  
  36.   
  37. //判断队列是否为空  
  38. int QueueIsEmpty()  
  39. {  
  40.     return (q == NULL);  
  41. }  
  42.   
  43. //put操作  
  44. void QueuePut( Item item)  
  45. {  
  46.     if(QueueIsEmpty())  
  47.     {  
  48.         q = (tail = NewNode(item, q));  
  49.     }  
  50.     else  
  51.     {  
  52.         tail->next = NewNode(item, tail->next);  
  53.         tail = tail->next;  
  54.     }  
  55.     printf("Put: %d\n", item);  
  56. }  
  57.   
  58. //get操作  
  59. Item QueueGet()  
  60. {  
  61.     if(q == NULL)  
  62.     {  
  63.         printf("序列为空!\n");  
  64.         return -1;  
  65.     }  
  66.   
  67.     Item firstItem = q->item;//序列的头元素  
  68.     Node* tmpNode = q;  
  69.     q = q->next;  
  70.     free(tmpNode);  
  71.     return firstItem;  
  72. }  
  73.   
  74. //测试程序  
  75. int main()  
  76. {  
  77.     QueueInit(maxN);  
  78.     QueuePut(2);  
  79.     QueuePut(3);  
  80.     QueuePut(4);  
  81.     printf("\n");  
  82.     printf("Get: %d\n", QueueGet());  
  83.     printf("Get: %d\n", QueueGet());  
  84.     printf("Get: %d\n", QueueGet());  
  85.     printf("Get: %d\n", QueueGet());  
  86.     system("pause");  
  87.     return 0;  
  88. }  


运行结果:


二、FIFO队列的数组实现

队列中的内容是数组中从head到tail的所有元素,到tail到达数组尾部时回卷到0,此程序的实现过程需要考虑队列满和队列空两种特殊状态,
本文采用2种方式实现:

1)设定FIFO队列的数组大小比客户将在队列放置的元素最大数目大1(From:《算法:C语言实现》P93)

 当head和tail重合时为空;当tail+1和head重合时为满
FIFO_Array_1.cpp
[cpp]  view plain  copy
  1. /************************************************************* 
  2. From:《算法:C语言实现》 P93 
  3. 功能:先进先出队列的数组形式实现:Init、Put、Get操作 
  4. 说明:  1)队列中的内容是数组中从head到tail的所有元素,到tail到达数组尾部时回卷到0 
  5.     2)设定FIFO队列的数组大小比客户将在队列放置的元素最大数目大1, 
  6.     当head和tail重合时为空;当head和tail+1重合时为满 
  7. 时间: 2015/02/03 
  8. 作者: quinn 
  9. **************************************************************/  
  10. #include<stdio.h>  
  11. #include <stdlib.h>  
  12. const int maxN = 10; //FIFO size  
  13. typedef int Item;  
  14. static Item *q; //队列  
  15. static int head, tail, N;  
  16. //队列初始化,初始化数组、头尾索引  
  17. void QueueInit(int maxN)  
  18. {  
  19.     q = (Item*)malloc(sizeof(*q) * (maxN+1));  
  20.     N = maxN + 1;  
  21.     head = N;  
  22.     tail = 0;  
  23. }  
  24.   
  25. //检查队列是否为空  
  26. int QueueIsEmpty()  
  27. {  
  28.     return (head % N) == tail;  // Get操作中head++位于%操作之后;Put操作中tail++位于%操作之前  
  29. }  
  30. int QueueIsFull()  
  31. {  
  32.         return (tail + 1)%N == head % N;  
  33. }  
  34. //推入队列,Put操作  
  35. void QueuePut(Item item)  
  36. {  
  37.     if (QueueIsFull())  
  38.     {  
  39.         printf("队列已满,Put: %d 操作失败\n", item);  
  40.         return;  
  41.     }  
  42.     q[tail++] = item;  
  43.     tail %= N;  
  44.   
  45.     printf("Put: %d\n", item);  
  46. }  
  47. //出队列,Get操作  
  48. Item QueueGet()  
  49. {  
  50.     if (QueueIsEmpty())  
  51.     {  
  52.         printf("此队列现为空,Get操作失败,返回-1\n");  
  53.         return -1;  
  54.     }  
  55.     head %= N;  
  56.     return q[head++];  
  57. }  
  58.   
  59. //测试程序  
  60. int main()  
  61. {  
  62.     QueueInit(maxN);  
  63.     for (int i = 0; i <= 10; i++)  
  64.     {  
  65.         QueuePut(i);  
  66.     }  
  67.     printf("\n");  
  68.     printf("Get: %d\n\n", QueueGet());  
  69.     for (int i = 0; i < 10; i++)  
  70.     {  
  71.         printf("Get: %d\n", QueueGet());  
  72.     }  
  73.     system("pause");  
  74.     return 0;  
  75. }  
运行结果

2)设定FIFO队列的数组大小和客户将在队列放置的元素最大数目相等

当put操作导致tail和head重合时,设定满标志flag_full = 1;(初始化设定flag_full= 0)
当get操作导致tail和head重合时,设定空标志flag_empty = 1;(初始化设定flag_empty = 1)

FIFO_Array_2.cpp
[cpp]  view plain  copy
  1. /************************************************************* 
  2. 功能:先进先出队列的数组形式实现:Init、Put、Get操作 
  3. 说明:1)设定FIFO队列的大小,队列中的内容是数组中从head到tail的 
  4.             所有元素,到tail到达数组尾部时回卷到0 
  5. 时间: 2015/02/03 
  6. 作者: quinn 
  7. **************************************************************/  
  8. #include<stdio.h>  
  9. #include <stdlib.h>  
  10. const int maxN = 10; //FIFO size  
  11. typedef int Item;  
  12. static Item *q;  
  13. static int head, tail;  
  14. static int flag_full = 0, flag_empty = 1; //队列满空标志  
  15. //队列初始化,初始化数组、头尾索引  
  16. void QueueInit(int maxN)  
  17. {  
  18.     printf("初始化FIFO大小为%d\n",maxN);  
  19.     q = (Item*)malloc(sizeof(*q) * maxN);  
  20.     head = 0;  
  21.     tail = 0;  
  22. }  
  23. //推入队列,Put操作  
  24. void QueuePut(Item item)  
  25. {  
  26.     if (flag_full)  
  27.     {  
  28.         printf("队列已满,Put:%d 操作失败\n",item);  
  29.         return;  
  30.     }  
  31.   
  32.     q[tail++] = item;  
  33.     tail %= maxN;  
  34.   
  35.     printf("Put: %d\n", item);  
  36.     flag_empty = 0; //put后非空  
  37.     if (tail  == head)//Put操作导致的head和tail重合时,队列满  
  38.     {  
  39.         flag_full = 1;  
  40.     }  
  41.   
  42. }  
  43.   
  44. //出队列,Get操作  
  45. Item QueueGet()  
  46. {  
  47.   
  48.     if (flag_empty)  
  49.     {  
  50.         printf("队列为空,Get操作失败,返回-1\n");  
  51.         return -1;  
  52.     }  
  53.   
  54.     head %= maxN;  
  55.   
  56.     flag_full = 0; //Get操作成功,满标志设为0  
  57.     if ((head+1) % maxN == tail) //Get导致head+1和tail重合,队列空  
  58.     {  
  59.         flag_empty = 1;  
  60.     }  
  61.   
  62.     return q[head++];  
  63.   
  64. }  
  65.   
  66. //测试程序  
  67. int main()  
  68. {  
  69.     QueueInit(maxN);  
  70.     for (int i = 0; i <= 10; i++)  
  71.     {  
  72.         QueuePut(i);  
  73.     }  
  74.     printf("\n");  
  75.     printf("Get: %d\n\n", QueueGet());  
  76.     for (int i = 0; i <= 10; i++)  
  77.     {  
  78.         printf("Get: %d\n", QueueGet());  
  79.     }  
  80.     system("pause");  
  81.     return 0;  
  82. }  

运行结果:



FIFO队列ADT的get操作和put操作不论使用数组还是链表都能在常数时间内实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值