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

栈和队列的组合体。

一:概念

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

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

二:编码

1:定义结构体

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

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

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:队尾入队

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

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

/// <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;
}

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;
}

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;}

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;}
}

经典数据结构和算法 双端队列 java相关推荐

  1. 【python】数据结构与算法—双端队列(二)

    一.双端队列的特点: 可以对两端进行操作:队尾入队,队首出队:队尾出队,队首入队: 二.双端队列要实现的操作: 三.代码块(链表实现) class Node():def __init__(self,d ...

  2. 【python】数据结构与算法—双端队列(一)

    一.双端队列的特点: 可以对两端进行操作:队尾入队,队首出队:队尾出队,队首入队: 二.双端队列要实现的操作: 三.代码块(顺序表实现): class Deque:def __init__(self) ...

  3. Proj1a 数据结构:双端队列| CS61B-Spring-2018

    主要任务 编写双端队列,能够addFirst, remove First, addLast, removeLast.并实现其他一些辅助功能. 使用两种数据结构来完成双端队列,分别是链表和数组. 要求这 ...

  4. apriori算法c++实现_经典数据结构与算法(四):Python/C/C ++实现队列类型双端队列数据结构...

    前期文章点击这里: 经典数据结构与算法(一):Python/C/C ++实现堆栈和队列 双端队列或双端队列是一种队列,其中可以从前面或后面执行元素的插入和删除.因此,它不遵循FIFO规则(先进先出). ...

  5. 经典算法题每日演练——第十九题 双端队列

    经典算法题每日演练--第十九题 双端队列 原文:经典算法题每日演练--第十九题 双端队列 话说大学的时候老师说妹子比工作重要~,工作可以再换,妹子这个...所以...这两个月也就一直忙着Fall in ...

  6. python 判断div 之间的内容是否为空_python实现数据结构与算法之双端队列实现

    简介 双端队列(deque, double-ended queue),是一种具有队列和栈的性质的数据结构.双端队列中的元素可以从两端弹出,其限定插入和删除操作在表的两端进行.双端队列可以在队列任意一端 ...

  7. 数据结构与算法笔记(五)——队列(FIFO队列、双端队列)

    一.FIFO队列 1.1.概念 队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出的(First In First Out)的线性表,简称FIFO.允许 ...

  8. Python 数据结构与算法 —— list与deque(双端队列)

    TimeComplexity - Python Wiki 1. 底层数据结构 list 的底层是数组(array),其最大的时间空间消耗出现在存储元素增长超过当前数组分配的大小时,所有元素都必须移动到 ...

  9. Python数据结构与算法(3.5)——双端队列

    Python数据结构与算法(3.5)--双端队列 0. 学习目标 1. 双端队列的基本概念 1.1 双端队列的基本概念 1.2 双端队列抽象数据类型 2. 双端队列的实现 2.1 顺序双端队列的实现 ...

最新文章

  1. tomcat容器是如何创建servlet类实例?用到了什么原理?
  2. 公司间采购的后台配置备忘录
  3. 3.PL_SQL——创建第一个匿名块(set,l,DBMS_OUTPUT.PUT_LINE())
  4. 以太坊ipfs_动手:Infura和以太坊上的IPFS入门
  5. vue 同一个页面路由无反应_vue参数不同但是跳转同一个路由页面,及name的作用...
  6. 【VRP】基于matlab遗传算法求解多中心的车辆路径规划问题【含Matlab源码 010期】
  7. js代码混淆 webpack-obfuscator
  8. DSGE模型的Stata实现简介
  9. 设计一个三阶巴特沃斯滤波器_巴特沃斯低通滤波器设计分析.doc
  10. 3904三极管是什么功能_想要单片机顺手,搞懂这些三极管知识!
  11. 随机过程(基本概念、平稳随机过程)
  12. 第三阶段应用层——1.7 数码相册—电子书(3)—轮询方式支持多输入
  13. 【Faster R-CNN论文精度系列】从Faster R-CNN源码中,我们“学习”到了什么?
  14. paper学习笔记 - PLE
  15. 算法基础题:木棍切割问题
  16. 小游戏算年龄(Java)
  17. 1.20 JQuery3:动画和特效
  18. python3学习笔记-元祖tupe
  19. visio2007类图实现关系
  20. 儒家经典三礼,你知道指的是哪三礼吗?它们有什么区别?

热门文章

  1. Linux0.11进程分配时间片的策略
  2. GDB 内写脚本调试程序
  3. linux通信机制总结
  4. linux删除文件夹命令6,linux 结合find命令进行文件的删除
  5. 数据结构 图的广度优先遍历 C++
  6. 监视mysql 哪些指标_MySQL 监控指标
  7. 计算机的桌面图标都没有了怎么办,电脑桌面图标都没了怎么办 怎么恢复
  8. MoreUnit与MoreUnit
  9. 版本更新带来的缓存问题_浏览器缓存原理总结
  10. php中的几种跳转语句以及各自的特点,PHP中的跳转语句有且仅有break和continue两个语句。...