加载中...

第十九题 双端队列


话说大学的时候老师说妹子比工作重要~,工作可以再换,妹子这个。。。所以。。。这两个月也就一直忙着Fall in love,嗨,慢慢调整心态吧,

这篇就选一个简单的数据结构聊一聊,话说有很多数据结构都在玩组合拳,比如说:块状链表,块状数组,当然还有本篇的双端队列,是的,它就是

栈和队列的组合体。

一:概念

     我们知道普通队列是限制级的一端进,另一端出的FIFO形式,栈是一端进出的LIFO形式,而双端队列就没有这样的限制级,也就是我们可以在

队列两端进行插入或者删除操作。

二:编码

1:定义结构体

    通常情况下,队列的内部都是采用数组来实现,而且带有两个指针head和tail来指向数组的区间段,为了充分利用数组空间,我们也会用%来实

现逻辑上的循环数组,如下图。

这里有一个注意的细节就是“size字段“,它是为了方便统计队列是否为满或者队列是否为空。

2:队尾入队

    刚才也说了,双端队列是可以在队列的两端进行插入和删除的,要注意的是我们用head和tail指针的时候,tail指针是指向元素的下一个位置,

而head指针是指向当前元素,所以我们可以从tail端push数据的时候只要”顺时针“下移一个位置即可。

    和队尾入队一样,我们只要将tail指针”逆时针“下移一个位置,当然有一个细节需要注意,就是tail指针有存在负值的情况,毕竟我们是做”--操作“的,

所以需要tail+maxSize,即:myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;

4:队首入队

    从head端来说,我们push数据的时候是head指针“逆时针”旋转,要注意的是同样要防止负数的产生,并且head指针是指向当前元素。

5:队首出队

    说到这个方法,我想大家应该都懂了双端队列的大概流程了,这个方法我也不用赘叙了。

当我们只使用Push_Tail和Pop_Tail的话,那它就是栈。

当我们只使用Push_Tail和Pop_Head的话,那它就是队列。

最后是全部代码:

  1. using System.Net;
  2. using System;
  3. using System.IO;
  4. using System.Collections.Generic;
  5. using System.Text;
  6. using System.Drawing;
  7. using System.Drawing.Imaging;
  8.  
  9. class Program
  10. {
  11. static void Main(string[] args)
  12. {
  13. DoubleQueue<int> queue = new DoubleQueue<int>();
  14.  
  15. queue.Push_Tail(10);
  16. queue.Push_Tail(20);
  17. queue.Push_Tail(30);
  18.  
  19. queue.Pop_Tail();
  20. queue.Pop_Tail();
  21. queue.Pop_Tail();
  22.  
  23. queue.Push_Tail(10);
  24. queue.Push_Head(20);
  25. queue.Push_Head(30);
  26. queue.Push_Head(30);
  27.  
  28. queue.Pop_Tail();
  29. queue.Pop_Tail();
  30. queue.Pop_Head();
  31.  
  32. queue.Push_Head(40);
  33. queue.Push_Tail(50);
  34. queue.Push_Tail(60);
  35. }
  36. }
  37.  
  38. /// <summary>
  39. /// 双端队列
  40. /// </summary>
  41. public class DoubleQueue<T>
  42. {
  43. public class MyQueue
  44. {
  45. public int head;
  46.  
  47. public int tail;
  48.  
  49. public int maxSize;
  50.  
  51. public int size;
  52.  
  53. public T[] list;
  54.  
  55. public MyQueue()
  56. {
  57. head = tail = size = 0;
  58. maxSize = 3;
  59. list = new T[maxSize];
  60. }
  61. }
  62.  
  63. MyQueue myQueue = new MyQueue();
  64.  
  65. /// <summary>
  66. /// 队尾入队
  67. /// </summary>
  68. /// <param name="t"></param>
  69. /// <returns></returns>
  70. public bool Push_Tail(T t)
  71. {
  72. //判断队列是否已满
  73. if (myQueue.size == myQueue.list.Length)
  74. return false;
  75.  
  76. myQueue.list[myQueue.tail] = t;
  77.  
  78. //顺时针旋转
  79. myQueue.tail = (myQueue.tail + 1) % myQueue.maxSize;
  80.  
  81. myQueue.size++;
  82.  
  83. return true;
  84. }
  85.  
  86. /// <summary>
  87. /// 队尾出队
  88. /// </summary>
  89. /// <param name="edges"></param>
  90. /// <param name="t"></param>
  91. public T Pop_Tail()
  92. {
  93. //判断队列是否已空
  94. if (myQueue.size == 0)
  95. return default(T);
  96.  
  97. //逆时针旋转(防止负数)
  98. myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;
  99.  
  100. var temp = myQueue.list[myQueue.tail];
  101.  
  102. //赋予空值
  103. myQueue.list[myQueue.tail] = default(T);
  104.  
  105. myQueue.size--;
  106.  
  107. return temp;
  108. }
  109.  
  110. /// <summary>
  111. /// 队首入队
  112. /// </summary>
  113. /// <param name="t"></param>
  114. /// <returns></returns>
  115. public bool Push_Head(T t)
  116. {
  117. //判断队列是否已满
  118. if (myQueue.size == myQueue.list.Length)
  119. return false;
  120.  
  121. //逆时针旋转(防止负数产生)
  122. myQueue.head = (--myQueue.head + myQueue.maxSize) % myQueue.maxSize;
  123.  
  124. //赋予元素
  125. myQueue.list[myQueue.head] = t;
  126.  
  127. myQueue.size++;
  128.  
  129. return true;
  130. }
  131.  
  132. /// <summary>
  133. /// 队首出队
  134. /// </summary>
  135. /// <param name="edges"></param>
  136. /// <param name="t"></param>
  137. public T Pop_Head()
  138. {
  139. //判断队列是否已空
  140. if (myQueue.size == 0)
  141. return default(T);
  142.  
  143. //获取队首元素
  144. var temp = myQueue.list[myQueue.head];
  145.  
  146. //原来单位的值赋默认值
  147. myQueue.list[myQueue.head] = default(T);
  148.  
  149. //顺时针旋转
  150. myQueue.head = (myQueue.head + 1) % myQueue.maxSize;
  151.  
  152. myQueue.size--;
  153.  
  154. return temp;
  155. }
  156. }


还没有评论.