前言
在计算机科学中,队列(Queue)和栈(Stack)是常见的数据结构,它们被广泛应用于算法和程序设计中。队列和栈都是一种线性数据结构,其中元素按照特定的顺序存储和访问。
队列是一种先进先出(First-In-First-Out,FIFO)的数据结构,类似于现实生活中排队的场景。元素从队列的一端(称为队尾)进入,从另一端(称为队头)出去。在队列中,最先进入的元素首先被访问和处理。
栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,类似于现实生活中的堆叠。元素只能从栈的顶部进行插入和移除操作。最后被插入的元素首先被访问和处理。
循环队列(Circular Queue)是对普通队列的一种改进。循环队列解决了普通队列在出队操作时,空间浪费的问题。当队列的尾指针指向数组的末尾时,如果有空闲位置存在,可以将尾指针重新指向数组的开头,从而实现循环利用空间。
队列、栈和循环队列都有各自的实现方式。在实际编程中,我们可以使用数组或链表来实现队列和栈。循环队列则通常使用数组实现。
接下来,我将为你详细介绍队列、栈和循环队列的实现方法和操作
一、解题思路
1.队列
1.定义一个数组,左右指针并对其进行初始化
2.判空方法:左右指针是否相等,若相等则代表该基础队列的空间为空
3.入队:将要入队的数据赋值到数组中右指针所指位置并将右指针加一
4.出队:将左指针所指位置返回并将左指针加一
5.返回头部数据:直接返回左指针对应的数组数据
6.返回尾部数据:返回右指针减一所对应的数组数据
2.栈
1.定义一个数组,当前队列中的元素个数并对其进行初始化
2.判空方法:当前队列中的元素个数是否为0
3.入栈:将要入队的数据赋值到数组中当前队列中的元素个数所指位置并将当前队列中的元素个数加一
4.出栈:将当前队列中的元素个数减一所指位置返回并将当前队列中的元素个数减一
5.返回栈顶数据:直接返回当前队列中的元素个数对应的数组数据
3.循环队列
1.定义一个数组,队列头部的索引,队列尾部的索引,当前队列中的元素个数,队列的最大容量,并对其进行初始化
2.判空方法:当前队列中的元素个数是否为0
3.判满方法:当前队列中的元素个数是否为队列的最大容量。
4.入队:如果队列已满,则返回 false;否则将元素插入到队列尾部的索引所指向的位置,更新队列尾部的索引的值,并增加当前队列中的元素个数。最后返回 true。
5.出队:如果队列为空,则返回 -1;否则取出队列头部的索引所指向的元素,更新队列头部的索引的值,并减少当前队列中的元素个数,最后返回取出的元素。
6.返回头部数据:如果队列为空则返回 -1,否则直接返回队列头部的索引对应的值
7.返回尾部数据:如果队列为空则返回 -1,否则判断队列尾部的索引,如果队列尾部的索引为0,这说明最后一个数据在数组尾部,直接返回队列的最大容量-1所对应的值,否则返回当前队列中的元素个数-1所对应的数组的值。
二、详细代码
代码如下(示例):
public class lianduishixian {
//java中原有的基础队列
public static class queue1 {
public Queue<Integer> queue=new LinkedList<>();
public boolean empty(){
return queue.isEmpty();
}
public boolean offer(int num){
return queue.offer(num);
}
public int poll(){
return queue.poll();
}
public int peek(){
return queue.peek();
}
public int size(){
return queue.size();
}
}
//队列实现
public static class queue2{
public int[] queue;
public int l;
public int r;
public queue2(int n){
queue=new int[n];
l=0;
r=0;
}
public boolean isEmpty(){
return l==r;
}
public void offer(int num){
queue[r++]=num;
}
public int poll(){
return queue[l++];
}
public int head(){
return queue[l];
}
public int tail(){
return queue[r-1];
}
public int size(){
return r-l;
}
}
//java自带的栈
public static class stack1 {
public Stack<Integer> stack=new Stack<>();
public boolean empty(){
return stack.isEmpty();
}
public void push(int num){
stack.push(num);
}
public int poll(){
return stack.pop();
}
public int peek(){
return stack.peek();
}
public int size(){
return stack.size();
}
}
//栈实现
public static class stack2{
public int[] stack;
public int size;
public stack2(int n){
stack=new int[n];
size=0;
}
public boolean isEmpty(){
return size==0;
}
public void push(int num){
stack[size++]=num;
}
public int pop(){
return stack[--size];
}
public int peek(){
return stack[size];
}
}
//循环队列实现
public static class MyCirularQueue{
public int[] queue;
public int l,r,size,limit;
public MyCirularQueue(int k){
queue=new int[k];
l=r=size=0;
limit=k;
}
public boolean enQueue(int value){
if(isfull()){
return false;
}else{
queue[r]=value;
r=(r+1)%limit;
size++;
return true;
}
}
public int deQueue(){
if(isempty()){
return -1;
}else{
int value=queue[l];
l=(l+1)%limit;
size--;
return value;
}
}
public int Front(){
if(isempty()){
return -1;
}else{
return queue[l];
}
}
public int Rear(){
if(isempty()){
return -1;
}else{
return queue[r==0?(limit-1):(r-1)];
}
}
public boolean isempty(){
return size==0;
}
public boolean isfull(){
return size==limit;
}
}
}
总结
队列、栈和循环队列都是重要的数据结构,各自适用于不同的场景和问题;它们的实现可以使用数组或链表,具体选择取决于需要支持的操作和性能需求;了解和熟练掌握这些数据结构的实现对于解决各种算法和数据处理问题至关重要。