数据结构之队列(循环队列)
1.算法衡量优劣之时间复杂度2.数据结构与算法之概念3.算法衡量优劣之空间复杂度4.数据结构之数组5.数据结构之链表6.数据结构之栈7.N-皇后问题8.算术表达式的表示法(即求值法)9.算术表达式求值法(表达式求值)之前序表示法求值10.算术表达式求值法(表达式求值)之后序表示法求值11.数据结构之队列(一般队列)
12.数据结构之队列(循环队列)
13.数据结构之队列(双向队列)14.数据结构之树(基本概念)15.数据结构之树(二叉树)16.数据结构之树(Huffman tree(赫夫曼树 / 霍夫曼树 / 哈夫曼树 / 最优二叉树))17.数据结构之树(二叉树的存储方式之数组)18.数据结构之树(二叉树的存储方式之链表)19.数据结构之树(遍历)20.数据结构之树(二叉运算树)21.数据结构之树(二叉搜索树)22.数据结构之树(线索树)23.数据结构之树(树转化为二叉树也叫二叉化)24.确定唯一二叉树循环队列
又称为环形队列,有如下4个特点:
- 在循环队列的定义中规定了两个索引指针:front 和 rear。front 指向第一个有效元素的位置,而rear 可以理解为用来记录队尾元素的下一个位置。
- 当队列为空时,
front == rear
; - 当队列满时,
(rear + 1) % n = front
. 这样可以让队列看起来像一个环状结构,并使得 front 和 rear 可以循环使用。 - 队列的大小为
n - 1
个元素(n-1是队列真实的容量),其中一个空位留给判断队列为空的条件。
循环队列是一种特殊的线性表,它的内部用数组来实现。
与普通的队列不同的是,如果队满时再入队一个元素,并不会导致队列溢出,而是继续从队头插入,覆盖原有元素。
相对于链式存储结构的队列,数组实现的循环队列更加高效。
Java
1 package org.allen.data.structure.queue; 2 3 import javax.swing.plaf.synth.SynthOptionPaneUI; 4 5 /** 6 * 循环队列 7 * <pre> 8 * 出队:front指向第一个有效元素,删除即可。 9 * 注意: 10 * (1)不要吧front直接设置为下标0,防止头尾指针混乱,无法判断队列为空还是已满 11 * (2)当尾指针指向队列的最后一个位置时,再插入一个数据,tail则指回到下标0,重新计算 12 * (3)对尾指针求模运算的结果需要加上队列长度,否则可能越界 13 * 入队:rear指向下一个空位,插入数据,更新rear值 14 * 注意:由于有空位,所以不会覆盖原始数据 15 * </pre> 16 */ 17 public class CircularQueue { 18 // private int N;// 队列长度 19 protected int N; // 队列长度,是其真实容量 + 1 20 private int[] array; // 存放数据的数组 21 private int start; // 队列头部 22 private int end; // 队列尾部 23 24 public CircularQueue(int capacity) { 25 this.N = capacity + 1; 26 this.array = new int[N]; 27 this.start = 0; 28 this.end = 0; 29 } 30 31 public boolean isEmpty() { 32 return start == end; 33 } 34 35 public boolean isFull() { 36 return (end + 1) % N == start; 37 } 38 39 public int size() { 40 if (end > start) { 41 return end - start; 42 } else { 43 return N - start + end; 44 } 45 } 46 47 public Integer peek() { 48 if (isEmpty()) { 49 throw new RuntimeException("Queue is empty"); 50 } 51 52 return array[start]; 53 } 54 55 public void enqueue(int item) { 56 if (isFull()) { 57 throw new RuntimeException("Queue is full"); 58 } 59 60 array[end] = item; 61 end = (end + 1) % N; 62 } 63 64 public int dequeue() { 65 if (isEmpty()) { 66 throw new RuntimeException("Queue is empty"); 67 } 68 69 int temp = array[start]; 70 start = (start + 1) % N; 71 72 return temp; 73 } 74 75 public static void main(String[] args) { 76 CircularQueue circularQueue = new CircularQueue(3); 77 // 1. 测试队列满 78 // circularQueue.enqueue(1); 79 // circularQueue.enqueue(2); 80 // circularQueue.enqueue(3); 81 // circularQueue.enqueue(4); 82 83 circularQueue.enqueue(1); 84 circularQueue.enqueue(2); 85 circularQueue.enqueue(3); 86 System.out.println(circularQueue.size()); // 3 87 System.out.println(circularQueue.peek()); // 1 88 System.out.println(circularQueue.isFull()); // true 89 System.out.println(circularQueue.isEmpty()); // false 90 System.out.println(circularQueue.N); // 4 91 92 System.out.println(circularQueue.dequeue()); // 1 93 System.out.println(circularQueue.dequeue()); // 2 94 System.out.println(circularQueue.dequeue()); // 3 95 System.out.println(circularQueue.dequeue()); // 报错 Queue is empty 96 97 } 98 99 }
输出:
1 2 3 4 5 6 7 8 9 10 11 12 | 3 1 true false 4 1 2 3 Exception in thread "main" java.lang.RuntimeException: Queue is empty at org.allen.data.structure.queue.CircularQueue.dequeue(CircularQueue.java: 66 ) at org.allen.data.structure.queue.CircularQueue.main(CircularQueue.java: 95 ) Disconnected from the target VM, address: '127.0.0.1:57545' , transport: 'socket' |
Python
1 class MyCircularDeque: 2 def __init__(self, k: int): 3 self.capacity = k + 1 # 额外空出一个位置作为约定 4 self.circularDeque = [0] * (k + 1) 5 self.front = 0 6 self.rear = 0 7 8 def is_empty(self) -> bool: 9 return self.front == self.rear 10 11 def is_full(self) -> bool: 12 return (self.rear + 1) % self.capacity == self.front 13 14 def insertFront(self, value: int) -> bool: 15 if self.is_full(): 16 return False 17 self.front = (self.front - 1 + self.capacity) % self.capacity 18 self.circularDeque[self.front] = value 19 return True 20 21 def insertLast(self, value: int) -> bool: 22 if self.is_full(): 23 return False 24 self.circularDeque[self.rear] = value 25 self.rear = (self.rear + 1) % self.capacity 26 return True 27 28 def deleteFront(self) -> bool: 29 if self.is_empty(): 30 return False 31 self.front = (self.front + 1) % self.capacity 32 return True 33 34 def deleteLast(self) -> bool: 35 if self.is_empty(): 36 return False 37 self.rear = (self.rear - 1 + self.capacity) % self.capacity 38 return True 39 40 def getFront(self) -> int: 41 if self.is_empty(): 42 return -1 43 return self.circularDeque[self.front] 44 45 def getRear(self) -> int: 46 if self.is_empty(): 47 return -1 48 return self.circularDeque[self.rear - 1]
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了