数据结构-循环队列和循环双端队列的多角度实现

文章目录

      • 1. 循环队列的数组形式实现
      • 2. 循环队列的链表实现
      • 3. 循环双端队列的数组形式实现
      • 4. 循环双端队列的链表实现

在力扣的题面如下
在这里插入图片描述
在这里插入图片描述

1. 循环队列的数组形式实现

其实循环队列的数组形式只有下面要注意的点,只要掌握了下面的这几点,代码层面上就没有什么问题了

用数组模拟的思路跟循环单向队列是完全一致的,要记住下面的几个点

  • 1 . first 指向的是头元素的下标 , last 指向的是尾元素的下一个位置的下标
  • 2 . 在申请数组空间的时候要多申请一个空间的目的是,讲判断空与判断满的条件区分开
  • 判断空就是 first == last 判断满就是 "first的下一个" == last;
    
  • 3 . 在循环队列里面,如何++,如何–?
  • ++ : (first + 1) % len  ;  (last + 1) % len;
    
  • -- : (first - 1 + len) % len  ;  (last - 1 + len) % len
    
  • 4 . 元素的个数 size == (last - fist + len) % len;

下面是数组形式的实现代码

class MyCircularQueue {int[] elementData;int first;int last;public MyCircularQueue(int k) {elementData = new int[k + 1];}public boolean enQueue(int value) {if(isFull()){return false;}elementData[last] = value;last = (last + 1)%  elementData.length;return true;}public boolean deQueue() {if(isEmpty()){return false;}first = (first + 1)%elementData.length;return true;}public int Front() {if(isEmpty()){return -1;}return elementData[first];}public int Rear() {if(isEmpty()){return  -1;}int index = last == 0 ? elementData.length - 1 : last -1;return elementData[index];}public boolean isEmpty() {return last == first;}public boolean isFull() {return first == (last + 1)  % elementData.length;}
}/*** Your MyCircularQueue object will be instantiated and called as such:* MyCircularQueue obj = new MyCircularQueue(k);* boolean param_1 = obj.enQueue(value);* boolean param_2 = obj.deQueue();* int param_3 = obj.Front();* int param_4 = obj.Rear();* boolean param_5 = obj.isEmpty();* boolean param_6 = obj.isFull();*/

2. 循环队列的链表实现

鉴于单链表的尾巴节点每次都要寻找,所以为了简便,我们采用双向链表进行模拟,注意,这里我们对于链表节点的定义就是我们LinkedList中的源码形式,有空可以去看看我们LinkedList的底层源码,这里其实就是多了个size来标记我们的链表节点数量
代码实现如下


/*** 尝试用双向链表来模拟循环队列*/
public class CircleQueue {/*** 下面是根据原代码模拟的定义的节点类* @param <T>*/static class Node<T> {public T item;public Node<T> prev;public Node<T> next;public Node (Node<T> prev,T item,Node<T> next) {this.prev = prev;this.item = item;this.next = next;}}/*** 下面是所需要的基本结构*/private Node first;private Node last;private int size;private int capacity;public CircleQueue(int k) {this.size = 0;first = last = null;capacity = k;}public boolean enQueue(int value) {if(isFull()){return false;}Node<Integer> node = new Node<>(null,value,null);if(first == null && last == null){first = node;last = node;}else{last.next = node;node.prev = last;last = node;}this.size++;return true;}public boolean deQueue() {if(isEmpty()){return false;}if(last == first){last = first = null;}else{first = first.next;first.prev.next = null;first.prev.item = null;}this.size--;return true;}public int Front() {if(isEmpty()){return -1;}return (int)first.item;}public int Rear() {if(isEmpty()){return -1;}return (int)last.item;}public boolean isEmpty() {return first == null && last == null;}public boolean isFull() {return this.size == this.capacity;}
}

3. 循环双端队列的数组形式实现

用数组实现队列源码层面是我们的ArrayDeque这个类完成的,这里不再多说了,和我们的1.用数组实现循环队列是一致的

/*** 首先尝试是数组来模拟循环双端队列* 其次我们再用双向链表来尝试模拟一下循环双端队列* 用数组模拟的思路跟循环单向队列是完全一致的,要记住下面的几个点* 1 . first 指向的是头元素的下标 , last 指向的是尾元素的下一个位置的下标* 2 . 在申请数组空间的时候要多申请一个空间的目的是,讲判断空与判断满的条件区分开*     判断空就是 first == last 判断满就是 "first的下一个" == last;* 3 . 在循环队列里面,如何++,如何--?*     ++ : (first + 1) % len  ;  (last + 1) % len;*     -- : (first - 1 + len) % len  ;  (last - 1 + len) % len* 4 . size == (last - fist + len) % len;*/
class MyCircularDeque {int[] elementData;int first;int last;public MyCircularDeque(int k) {elementData = new int[k + 1];first = last = 0;}public boolean insertFront(int value) {if(isFull()){return false;}first = (first - 1 + elementData.length) % elementData.length;elementData[first] = value;return true;}public boolean insertLast(int value) {if(isFull()){return false;}elementData[last] = value;last = (last + 1) % elementData.length;return true;}public boolean deleteFront() {if(isEmpty()){return false;}first = (first + 1) % elementData.length;return true;}public boolean deleteLast() {if(isEmpty()){return false;}last = (last - 1 + elementData.length) % elementData.length;return true;}public int getFront() {if(isEmpty()){return -1;}return elementData[first];}public int getRear() {if(isEmpty()){return -1;}return elementData[(last - 1 + elementData.length) % elementData.length];}public boolean isEmpty() {return first == last;}public boolean isFull() {return (last + 1) % elementData.length == first;}
}

4. 循环双端队列的链表实现

其实就是比2.多了一个addFirst,和 removeLast
代码实现如下


/*** 下面我们尝试使用双向链表来模拟我们的循环双端队列*/
class MyCircularDequeUseLinkedList {static class Node<T> {Node<T> prev;T item;Node<T> next;public Node(Node<T> prev,T item,Node<T> next){this.prev = prev;this.item = item;this.next = next;}}private int size;private int capacity;private Node first;private Node last;public MyCircularDequeUseLinkedList(int k) {this.size = 0;last = first = null;this.capacity = k;}public boolean insertFront(int value) {if(isFull()){return false;}Node<Integer> node = new Node<>(null,value,null);if(isEmpty()){first = last = node;}else{node.next = first;first.prev = node;first = node;}size++;return true;}public boolean insertLast(int value) {if(isFull()){return false;}Node<Integer> node = new Node<>(null,value,null);if(isEmpty()){first = last = node;}else{last.next = node;node.prev = last;last = node;}size++;return true;}public boolean deleteFront() {if(isEmpty()){return false;}if(first == last){last = first = null;}else{first = first.next;first.prev.next = null;first.prev.item = null;first.prev = null;}size--;return true;}public boolean deleteLast() {if(isEmpty()){return false;}if(last == first){first = last = null;}else{last = last.prev;last.next.prev = null;last.next.item = null;last.next = null;}size--;return true;}public int getFront() {if(isEmpty()){return -1;}return (int)first.item;}public int getRear() {if(isEmpty()){return -1;}return (int)last.item;}public boolean isEmpty() {return first == null && last == null;}public boolean isFull() {return this.size == this.capacity;}
}

为什么不用单链表实现的原因其实是单链表每次想尾插都要走到最后一个位置,时间复杂度太高,有兴趣的话也可以自己模拟一下试试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/640978.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

图论基础知识 深度搜索(DFS,Depth First Search),广度搜索(BFS,Breathe First Search)

图论基础知识 学习记录自代码随想录 dfs 与 bfs 区别 dfs是沿着一个方向去搜&#xff0c;不到黄河不回头&#xff0c;直到搜不下去了&#xff0c;再换方向&#xff08;换方向的过程就涉及到了回溯&#xff09;。 bfs是先把本节点所连接的所有节点遍历一遍&#xff0c;走到下…

windows SDK编程 --- 消息(3)

前置知识 一、消息的分类 1. 鼠标消息 处理与鼠标交互相关的事件&#xff0c;比如移动、点击和滚动等。例如&#xff1a; WM_MOUSEMOVE: 当鼠标在窗口客户区内移动时发送。WM_LBUTTONDOWN: 当用户按下鼠标左键时发送。WM_LBUTTONUP: 当用户释放鼠标左键时发送。WM_RBUTTOND…

C语言--基础面试真题

1、局部变量和静态变量的区别 普通局部变量和静态局部变量区别 存储位置&#xff1a; 普通局部变量存储在栈上 静态局部变量存储在静态存储区 生命周期&#xff1a; 当函数执行完毕时&#xff0c;普通局部变量会被销毁 静态局部变量的生命周期则是整个程序运行期间&#…

Oracle 21 C 安装详细操作手册,并配置客户端连接

Oracle 21 C 安装详细操作手册 Win 11 Oracle 21C 下载&#xff1a; Database Software Downloads | Oracle 中国 云盘共享 链接&#xff1a;https://pan.baidu.com/s/12XCilnFYyLFnSVoU_ShaSA 提取码&#xff1a;nfwc Oracle 21C 配置与登陆&#xff1a; 开始菜单 NetMa…

熊猫电竞赏金赛系统源码 APP+H5双端源码附搭建教程下载

熊猫电竞赏金系统简介 熊猫电竞赏金电竞系统 赏金赛源码&#xff0c;用户通过平台打比赛&#xff0c;赢了获得奖金奖励&#xff0c; 金币赛、赏金赛、vip赛等种赛事 可开王者荣耀、和平精英比赛 支持1v1、单排、双排组、战队排等多种比赛模式 支持QQ区、微信区 游戏玩的好…

Android——log的记忆

1.Java的 backtrace(堆栈log) 上述是一个空指针异常&#xff0c;问题出现在sgtc.settings&#xff0c;所以属于客户UI问题。 2.WindowManager(管理屏幕上的窗口和视图层次结构) 3.ActivityManager(管理应用程序生命周期和任务栈)

mac上VMware fusion net模式无法正常使用的问题

更新时间&#xff1a;2024年04月22日21:39:04 1. 问题 环境&#xff1a; intel芯片的macbook pro VMware fusion 13.5.1 无法将“Ethernet0”连接到虚拟网络“/dev/vmnet8”。在这里显示这个之后&#xff0c;应该是vmnet8的网段发生了冲突&#xff0c;所以导致无法正常使用…

text-shadow详解

text-shadow详解 属性定义及使用说明 text-shadow是CSS3中用于给文本添加阴影效果的属性。它允许您为文本内容添加一个或多个阴影&#xff0c;以增强视觉效果&#xff0c;创建立体感或装饰性文字外观。 语法 text-shadow: h-shadow v-shadow blur-radius spread-radius col…

yolov5_深度学习模型训练程序的暂停与恢复

问&#xff1a; 为什么要中断yolov5模型的训练&#xff1f; 答&#xff1a; 训练数据量大且过程漫长&#xff0c;电脑总要休息的嘛 简单直说&#xff1a; 1. 暂停 &#xff1a; 键盘输入&#xff1a; ctrl c这里以从第二次迭代中断为例&#xff1a; 2. 恢复模型训练 &am…

ChatGPT在线网页版(与GPT Plus会员完全一致)

ChatGPT镜像 今天在知乎看到一个问题&#xff1a;“平民不参与内测的话没有账号还有机会使用ChatGPT吗&#xff1f;” 从去年GPT大火到现在&#xff0c;关于GPT的消息铺天盖地&#xff0c;真要有心想要去用&#xff0c;途径很多&#xff0c;别的不说&#xff0c;国内GPT的镜像…

OpenCV-复数矩阵点乘ComplexMatrixDotMultiplication

作者&#xff1a;翟天保Steven 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 需求说明 一般用到FFT&#xff0c;就涉及到复数的计算&#xff0c;为了便于调用&#xff0c;我自行封装了一个简单的复数矩阵点乘…

Linux I2C(二) - I2C软硬件架构

1&#xff0c;I2C的总线拓扑 2&#xff0c;I2C S/W topology linux kernel I2C framework使用如下的软件拓扑抽象I2C硬件&#xff08;我们可以一起领会一下其中的“设备模型”思想&#xff09;&#xff1a; 1&#xff09;platform bus&#xff08;/sys/bus/platform&#xff0…