一、队列
1. 队列的概念
- 队列的核心理念是:先进先出;
- 队列是一种特殊的线性表:它只允许在表的前端
(front)
进行删除操作,而在表的后端(tail)进行插入操作
; - 队列和栈都是一种操作受限的线性表,其中进行插入操作的端称之为队尾,进行删除操作的端称之为队首;
2.队列的属性
getFront()
:获取队首的元素,但不进行出队操作;getSize()
:获取队列中元素的数量;isEmpty()
:判断队列是否为空;enqueue()
:在队尾tail
插入元素;dequeue()
:在队首front
删除元素;
上述队列的属性抽象成接口,其代码实现如下:
/**
* @Author: zjtMeng
* @Date: 2019/12/22 18:47
* @Version 1.0
*/
public interface Queue<E> {
void enqueue(E e);
E dequeue();
E getFront();
int getSize();
boolean isEmpty();
}
二、普通队列ArrayQueue
-
普通队列概念是:底层通过数组来实现,且通过调用
addLast()
实现入队操作,调用removeFirst()
实现出队操作; -
此部分会用到之前自己封装的数组,其博客地址如下:自己封装的数组Array
2.1基本方法的实现:
- 队列的有参构造方法和无参构造方法初始化队列的容积,可以直接调用
Array
的构造方法
public ArrayQueue(int capacity){
array =new Array<>(capacity);
}
public ArrayQueue(){
array = new Array<>();
}
- 入队操作,通过调用
Array
中的addLast()
方法。由于Array
中在设计addLast()
方法时,已经考虑了扩容的操作,因此实现队列的入队操作时,不必考虑扩容这部分情况;Array
中addLast()
方法和扩容操作代码:
/**
* 调用add()方法,实现在所有元素之后添加一个新元素
*/
public void addLast(E e){
add(size,e);
}
/**
* 在index位置上插入元素e
* @param index
* @param e
*/
public void add(int index,E e){
//判断传入的插入位置参数是否规范以及合乎要求,
if (index <0 || index> size)
throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
//判断当前数组是否已经达到容量了
if (size == data.length)
//调用resize()方法,进行扩容
resize(2 * data.length);
//从插入位置开始,后面的所有元素全部向后挪一位
for (int i=size-1; i>=index; i--)
data[i+1] = data[i];
data[index] = e;
size++;
}
/**
* 扩容
* @param newCapacity
*/
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity];
for (int i=0; i<size; i++){
newData[i] = data[i];
}
data = newData;
}
此处队列调用Array
中的addLast()
方法,可以实现入队操作;
- 出队操作,通过调用
Array
中removeFirst()
方法。同样的,由于Array
中在设计removeFirst()
方法时,已经考虑了缩容的操作,因此实现队列的入队操作时,不必考虑扩容这部分情况;Array
中removeFirst()
方法和缩容操作代码:
/**
* 删除数组最后一个元素,返回删除的元素
* @return
*/
public E removeLast(){
return remove(size-1);
}
/**
* 从数组中删除指定位置的元素,并返回删除的元素
* @param index
* @return
*/
public E remove(int index){
//判断传入的插入位置参数是否规范以及合乎要求,
if (index <0 || index> size)
throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
E ret = data[index];
for (int i = index; i < size ; i++) {
data[i] = data[i+1];
}
size--;
//此处将移除位置置为null,是为了 loitering object != memory leak
data[size] = null;
//当数组元素减少到一定程度(数组的容量的1/4。而不是1/2)时,数组容量缩小一倍,从而避免数组在1/2容积节点处位置来回扩容缩容操作
if(size == data.length / 4 && data.length / 2 != 0)
resize(data.length / 2);
return ret;
}
因此此处队列调用Array
中的removeFirst()
方法,可以实现出队操作;
2.2普通队列的实现
代码如下:
package dataStructure.chapter3;
import dataStructure.chapter1.Array;
/**
* @Author: zjtMeng
* @Date: 2019/12/22 18:50
* @Version 1.0
*/
public class ArrayQueue<E> implements Queue<E> {
private Array<E> array;
//有参构造方法
public ArrayQueue(int capacity){
array =new Array<>(capacity);
}
public ArrayQueue(){
array = new Array<>();
}
@Override
public void enqueue(E e) {
array.addLast(e);
}
@Override
public E dequeue() {
return array.removeFirst();
}
@Override
public E getFront() {
return array.getFirst();
}
@Override
public int getSize() {
return array.getSize();
}
@Override
public boolean isEmpty() {
return array.isEmpty();
}
public int getCapacity(){
return array.getCapacity();
}
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Queue");
res.append("front[");
for (int i = 0; i<array.getSize(); i++){
res.append(array.get(i));
if (i != array.getSize()-1)
res.append(", ");
}
res.append("] tail");
return res.toString();
}
}
来源:CSDN
作者:zjtMeng
链接:https://blog.csdn.net/zjt980452483/article/details/103753350