本文介绍: 通常情况下,队列内部都是采用数组实现,而且带有两个指针 headtail 来指向数组区间段,为了充分利用数组空间我们也会用 % 来实现逻辑上的循环数组,如下图这里一个注意的细节就是“size 字段“,它是为了方便统计队列是否为满或者队列是否为空

话说有很多数据结构都在玩组合拳,比如说:块状链表,块状数组,当然还有本篇双端队列,是的,它就是栈和队列的组合体。

一、概念

我们知道普通队列是限制级的一端进,另一端出的 FIFO 形式,栈是一端进出的 LIFO 形式,而双端队列就没有这样的限制,也就是我们可以在队列两端进行插入或者删除操作

二、编码

2.1、定义结构

通常情况下,队列的内部都是采用数组实现,而且带有两个指针 headtail 来指向数组的区间段,为了充分利用数组空间我们也会用 % 来实现逻辑上的循环数组,如下图
image.png

 public class MyQueue
 {
     public int head;

     public int tail;

     public int maxSize;

     public int size;

     public T[] list;

     public MyQueue()
     {
         head = tail = size = 0;
         maxSize = 3;
         list = new T[maxSize];
     }
 }

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

2.2、队尾入队

刚才也说了,双端队列是可以在队列的两端进行插入删除的,要注意的是我们headtail 指针的时候,tail 指针指向元素的下一个位置
head 指针指向当前元素,所以我们可以从 tail 端 push 数据的时候只要”顺时针“下移一个位置即可

 /// <summary&gt;
 /// 队尾入队
 /// </summary>
 /// <param name="t"></param>
 /// <returns></returns>
 public bool Push_Tail(T t)
 {
     //判断队列是否已满
     if (myQueue.size == myQueue.list.Length)
         return false;

     myQueue.list[myQueue.tail] = t;

     //顺时针旋转
     myQueue.tail = (myQueue.tail + 1) % myQueue.maxSize;

     myQueue.size++;

     return true;
 }

2.3、队尾出队

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

myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;
 /// <summary>
 /// 队尾出队
 /// </summary>
 /// <param name="edges"></param>
 /// <param name="t"></param>
 public T Pop_Tail()
 {
     //判断队列是否已空
     if (myQueue.size == 0)
         return default(T);

     //逆时针旋转(防止负数)
     myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;

     var temp = myQueue.list[myQueue.tail];

     //赋予空值
     myQueue.list[myQueue.tail] = default(T);

     myQueue.size--;

     return temp;
 }

2.4、队首入队

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

 /// <summary>
 /// 队首入队
 /// </summary>
 /// <param name="t"></param>
 /// <returns></returns>
 public bool Push_Head(T t)
 {
     //判断队列是否已满
     if (myQueue.size == myQueue.list.Length)
         return false;

     //逆时针旋转(防止负数产生)
     myQueue.head = (--myQueue.head + myQueue.maxSize) % myQueue.maxSize;

     //赋予元素
     myQueue.list[myQueue.head] = t;

     myQueue.size++;

     return true;
 }

2.5、队首出队

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

 /// <summary>
 /// 队首出队
 /// </summary>
 /// <param name="edges"></param>
 /// <param name="t"></param>
 public T Pop_Head()
 {
     //判断队列是否已空
     if (myQueue.size == 0)
         return default(T);

     //获取队首元素
     var temp = myQueue.list[myQueue.head];

     //原来单位的值赋默认值
     myQueue.list[myQueue.head] = default(T);

     //顺时针旋转
     myQueue.head = (myQueue.head + 1) % myQueue.maxSize;

     myQueue.size--;

     return temp;
 }

从上面的四个方法可以看出:
当我们只使用 Push_Tail 和 Pop_Tail 的话,那它就是栈。
当我们只使用 Push_Tail 和 Pop_Head 的话,那它就是队列。
最后是全部代码

 using System.Net;
 using System;
 using System.IO;
 using System.Collections.Generic;
 using System.Text;
 using System.Drawing;
 using System.Drawing.Imaging;
 
 class Program
 {
     static void Main(string[] args)
     {
         DoubleQueue<int> queue = new DoubleQueue<int>();
 
         queue.Push_Tail(10);
         queue.Push_Tail(20);
         queue.Push_Tail(30);
 
         queue.Pop_Tail();
         queue.Pop_Tail();
         queue.Pop_Tail();
 
         queue.Push_Tail(10);
         queue.Push_Head(20);
         queue.Push_Head(30);
         queue.Push_Head(30);
 
         queue.Pop_Tail();
         queue.Pop_Tail();
         queue.Pop_Head();
 
         queue.Push_Head(40);
         queue.Push_Tail(50);
         queue.Push_Tail(60);
     }
 }
 
 /// <summary>
 /// 双端队列
 /// </summary>
 public class DoubleQueue<T>
 {
     public class MyQueue
     {
         public int head;
 
         public int tail;
 
         public int maxSize;
 
         public int size;
 
         public T[] list;
 
         public MyQueue()
         {
             head = tail = size = 0;
             maxSize = 3;
             list = new T[maxSize];
         }
     }
 
     MyQueue myQueue = new MyQueue();
 
     /// <summary>
     /// 队尾入队
     /// </summary>
     /// <param name="t"></param>
     /// <returns></returns>
     public bool Push_Tail(T t)
     {
         //判断队列是否已满
         if (myQueue.size == myQueue.list.Length)
             return false;
 
         myQueue.list[myQueue.tail] = t;
 
         //顺时针旋转
         myQueue.tail = (myQueue.tail + 1) % myQueue.maxSize;
 
         myQueue.size++;
 
         return true;
     }
 
     /// <summary>
     /// 队尾出队
     /// </summary>
     /// <param name="edges"></param>
     /// <param name="t"></param>
     public T Pop_Tail()
     {
         //判断队列是否已空
         if (myQueue.size == 0)
             return default(T);
 
         //逆时针旋转(防止负数)
         myQueue.tail = (--myQueue.tail + myQueue.maxSize) % myQueue.maxSize;
 
         var temp = myQueue.list[myQueue.tail];
 
         //赋予空值
         myQueue.list[myQueue.tail] = default(T);
 
         myQueue.size--;
 
         return temp;
     }
 
     /// <summary>
     /// 队首入队
     /// </summary>
     /// <param name="t"></param>
     /// <returns></returns>
     public bool Push_Head(T t)
     {
         //判断队列是否已满
         if (myQueue.size == myQueue.list.Length)
             return false;
 
         //逆时针旋转(防止负数产生)
         myQueue.head = (--myQueue.head + myQueue.maxSize) % myQueue.maxSize;
 
         //赋予元素
         myQueue.list[myQueue.head] = t;
 
         myQueue.size++;
 
         return true;
     }
 
     /// <summary>
     /// 队首出队
     /// </summary>
     /// <param name="edges"></param>
     /// <param name="t"></param>
     public T Pop_Head()
     {
         //判断队列是否已空
         if (myQueue.size == 0)
             return default(T);
 
         //获取队首元素
         var temp = myQueue.list[myQueue.head];
 
         //原来单位的值赋默认值
         myQueue.list[myQueue.head] = default(T);
 
         //顺时针旋转
         myQueue.head = (myQueue.head + 1) % myQueue.maxSize;
 
         myQueue.size--;
 
         return temp;
     }
 }

原文地址:https://blog.csdn.net/s1t16/article/details/134612313

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_14239.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注