当前位置: 首页 > news >正文

数据结构5.0

大家好,今天是队列的知识哦~

目录

一、概念

1.0单链表

2.0双链表

3.0数组

二、队列的方法

1.0 offer方法

 2.0 poll方法

3.0 peek方法

4.0 isEmpty方法

三、队列的题目

1.0 用队列实现栈

2.0 用栈实现队列

3.0 设计循环队列


一、概念

数组 、单链表和双链表都可以实现队列

1.0单链表

入栈操作:单链表是头插  时间复杂度O(1) 出栈操作:单链表是删除头节点

这样实现了 队列 先进先出的特点

2.0双链表

头插 尾删   可以实现队列

尾插 头删   也可以实现队列

只要保证特性满足 队列的特性即可

源码里面是尾插头删

3.0数组

队尾入 队头出 如果放到数组里面很难搞 队尾已经到了数组长度的极限了,队头删了还有空间

我们会发现 如果把数组前面当作队头  数组最后当作队尾 

当队尾一直遍历到数组末尾 不能加数据了 但是随着队头出  数组还是有空间的呀

如果把数组卷起来 头尾相连  得到一个循环数组  这样就能更大化的利用空间了

这里我们的rear补药rear++

用下面这个公式可以是rear循环走:rear=(rear+1)%len  front也一样 不会越界

有关这个部分的内容放到下面的题目里面了  622. 设计循环队列 - 力扣(LeetCode)

二、队列的方法

Queue是个接口,底层是通过链表实现的

方法预览:

1.0 offer方法

入队列 我们用的是双链表  源码里面的offer是用的头插法

所以逻辑和我们双链表的头插几乎一样

这个usedSize 可以搞一个

代码这里是尾插

下面是代码:

public void offer (int e){
ListNode newNode = new ListNode(e);
if(front ==null){front = rear = node;}else{last.next = node;node.prev = last;last = node;}uesdSize++;
}

 2.0 poll方法

同理  类似双链表的删除头节点的方法

下面是代码:

 public int poll(){if(front == null){return -1;}int ret = front.val;;if(front == rear){front = null;rear = null;usedSize--;}front = front.next;front.prev= null;usedSize--;return ret;}

3.0 peek方法

获取队头元素  也就是获取双链表头结点元素

要注意分情况讨论

public int peek(){if(front == null){return -1;}return front.val;}

4.0 isEmpty方法

public boolean isEmpty(){return usedSize == 0;
}

三、队列的题目

1.0 用队列实现栈

225. 用队列实现栈 - 力扣(LeetCode)

思路分析:

如何用队列实现栈呢? 如何用队列让先进的后出

方法有很多种 这里我们讲解一个方法  用交换法

两个队列   队列1和队列2  存入的时候 都存到queue1里面

要实现pop方法和top方法的时候  明确我们要删除的是后进的那个元素

我们将队列1添加的元素出队到队列2   剩下最后一个元素 (这个元素就是后进的那个)

用popped记录下后删除  然后交换队列把那些在队列2的元素交换回来

top方法的大体思路同样如此哦 这里就不再赘述了 多犯错误多调试比较快

class MyStack {Queue<Integer> queue1;Queue<Integer> queue2;public MyStack() {queue1 = new LinkedList<>();queue2 = new LinkedList<>();}public void push(int x) {queue1.offer(x);}public int pop() {while(queue1.size()>1){queue2.offer(queue1.poll());}int popped=queue1.poll();Queue<Integer> temp = queue1;queue1=queue2;queue2=temp;return popped;}// while(queue1.isEmpty()){// queue2.offer(queue1.getLast());// }// queue2.poll();public int top() {// return queue2.peek();while(queue1.size()>1) {queue2.offer(queue1.poll());}int top = queue1.peek();queue2.offer(queue1.poll());Queue<Integer> temp = queue1;queue1=queue2;queue2=temp;return top;}public boolean empty() {return queue1.isEmpty() && queue2.isEmpty();}}

2.0 用栈实现队列

232. 用栈实现队列 - 力扣(LeetCode)

思路分析:

要达到的目标是用栈模拟实现队列先进先出的结构

栈的结构是先进后出

我们可以用两个栈  一个用来push 一个用来pop和peek

我们要实现先进先出 把栈1里面的元素push到栈2里面

此时栈2的栈顶元素就是先进的元素 然后用栈2的pop方法peek方法就可以达到目的

要注意的点是:判断栈2是否为空

有时候 栈2的元素还没有pop完呢 栈1里面又加入新的元素了

这个时候我们pop也是从栈2里面出 毕竟栈2的元素比栈1早进

然后直到栈2为空了  我们想要pop了 再把栈1的元素push到栈2pop

所以pop方法和peek方法 要先判断栈2是否为空

下面是代码:

class MyQueue {private Stack<Integer>  stack1;private Stack<Integer> stack2;public MyQueue() {stack1= new Stack<>();stack2= new Stack<>();}public void push(int x) {stack1.push(x);}public int pop() {if(empty()){return -1;}// 为什么要判断 stack是否为空呢 难道还能中途//确保stack1 的元素只会在stack为空时倒入    //如果stack1里面有元素 stack2里面也有元素 stack里面的早 所以弹stack2//stack2为空了再倒入if(stack2.isEmpty()){while(! stack1.isEmpty()) {stack2.push(stack1.pop());}}return stack2.pop();}public int peek() {if(empty()) return -1;if(stack2.isEmpty()) {while(! stack1.isEmpty()) {stack2.push(stack1.pop());}}return stack2.peek();}public boolean empty() {return stack1.isEmpty()&&stack2.isEmpty();}
}

3.0 设计循环队列

622. 设计循环队列 - 力扣(LeetCode)

我们定义了一个数组之后 开始往里面放元素呀 

rear和front都在数组0下标   放入一个元素 队头front不变 队尾rear往后面加

这样直到数组满了  对应上面图片第一张 此时rear从7下标到了0小标 这个时候的处理方法有三种

第一种是  定义usedSize来记录  uedSize和len的比较

第二种是  可以使用标记 定义一个flag类型的变量 相遇的时候flag定义为false或者true

第三种是 浪费一个空间来区分  我们重点讲解这个内容

如果rear的下一个就是front  证明就是满的

rear如何实现 循环着走数组呢? 

rear=(rear+1)%len;   这个公式满足了rear在数组里 面循环  不会出现数组越界异常

最后 front也得因为删除队列元素 而在数组里面循环 当然这个是后话

下面开始各种方法的讲解:

(1)判断满空的方法:为什么是rear=front呢  因为这里的rear和front因为数组是循环的

                                       它们的位置不是固定的在开头 

(2)判断满:用到rear的循环走公式碰到了front

就是要判断 (rear+1)%elem.length == front;

(3)构造器  为什么要k+1 呢   因为我们用的方法是浪费一个空间  所以创建的时候就多一个 

                      这样就能有k个位置存放元素了

(4)入队 enQueue:入队的时候我们首先要判断满了没有  rear位置放上元素和rear位置的更新

         要注意的地方是:我们不能使用rear++ 代码里面用哪个公式是为了 实现rear的循环

(5)出队 deQueue : 出队 我们首先要判断是不是空呢  注意出队的时候 直接更新front节点就可以

         要注意的地方是:front 也得循环着走  所以也用到了那个公式

(6)从队首获得元素:这里的注意点是还是要提前判断循环队列是不是空的呢

(7)从队尾获得元素:这个要注意的是分类讨论   根据情况 

        如果rear的下标不是0  那么返回的是rear前面的元素  rear-1  前面我们也讲过 rear指向下一个

        可插入的位置   

        如果rear的下标是0 那么返回的是 数组长度下标减一  这个特殊情况在图片上面有所呈现

下面是代码:

class MyCircularQueue {int rear ;//队尾下表int front ;//队头下标int elem[] ;public MyCircularQueue(int k) {//构造器 设置队列的长度为kthis.elem= new int[k+1];// rear= (rear+1)%elem.length;}public boolean enQueue(int value) {if(isFull()) {return false;}elem[rear]=value;//rear++;  这样容易越界rear= (rear+1)%elem.length;return true;}public boolean deQueue() {//出 front往后面走就可以了// 空的 不能出if(isEmpty()){return false;}//不空 front往后走front=(front+1)%elem.length;return true;}public int Front() {//从队首获得元素if (isEmpty()){return -1;}return elem[front];}public int Rear() {//得到队尾元素if (isEmpty()) {return -1;}int index  = (rear == 0)? elem.length-1 : rear-1;return elem[index];}public boolean isEmpty() {return front == rear;}public boolean isFull() {if((rear+1)%elem.length == front){return true;}return false;}
}

以上 就是队列的知识咯~ 遍历一个节点

感谢大家的支持

更多内容还在加载中...........

如有问题欢迎批评指正,祝大家生活愉快、学习顺利!!!

http://www.xdnf.cn/news/366715.html

相关文章:

  • YOLO数据集标注工具LabelImg(打包Exe版本及使用)
  • 请求从发送到页面渲染的全过程
  • 体育数据库:搭建体育应用的核心「数据引擎」
  • PHP:互联网时代的经典编程语言魅力与未来展望
  • 关于大数据的基础知识(一)——定义特征结构要素
  • 人工智能顶会ICLR 2025论文分享│PointOBB-v2:更简单、更快、更强的单点监督有向目标检测
  • 红黑树算法笔记(一)
  • 聚焦边缘 AI 推理,Akamai 发布最新云与 AI 战略
  • 火山引擎火山云主推产品
  • 两根485线支持多少通信协议
  • C++Primerplus编程练习 第六章
  • 操作系统 == 内存管理
  • postgresql 参数wal_level
  • 【计算机网络-数据链路层】以太网、MAC地址、MTU与ARP协议
  • 7:点云处理—眼在手外标定
  • Grafana v10.1.5 升级至最新v12.0.0
  • 18.模方ModelFun设置教程
  • CSdiy java 07
  • GET请求如何传复杂数组参数
  • uniapp 和 webview 之间的通信
  • 上班摸鱼远程打游戏,哪款远控软件好用点?
  • 服务逃生(隐藏)-困难-其他,排序
  • 【Java基础】——集合篇
  • 使用Tomcat部署war包查看内存使用情况
  • 【0-3h PN相关2】GNSS天顶总延迟数据同化对意大利短期水汽和降水预报影响的研究
  • c++:编译链接过程
  • 40-算法打卡-二叉树-深度优先(前、中、后序遍历)-递归遍历-第四十天
  • Langchain、RAG、Agent相关
  • 【MyBatis-6】MyBatis动态SQL:灵活构建高效数据库查询的艺术
  • AI融合SEO关键词智能优化