队列
- 队列也是一种线性结构
- 相比数组队列对应的操作是数组的子集
- 只能从一端(队尾)添加元素, 只能从另一端(队首)取出元素
比如去银行办业务 队列是一种先进先出的数据结构,(FIFO) 接口
package com.qcx.algo.day07.implqueue;
public interface Queue<E> {
int getSize();
boolean isEmpty();
void enqueue(E e);
E dequeue();
E getFront();
}
实现类
package com.qcx.algo.day07.implqueue;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
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 int getSize() {
return array.getSize();
}
@Override
public boolean isEmpty() {
return array.isEmpty();
}
@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 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();
}
public static void main(String[] args) {
Queue<Integer> queue = new ArrayQueue<>();
for (int i = 0; i < 10; i++) {
queue.enqueue(i);
System.out.println(queue);
if (i%3==2){
queue.dequeue();
System.out.println(queue);
}
}
}
}
时间复杂度分析
int getSize(); o(1)
boolean isEmpty(); o(1)
void enqueue(E e); o(1)
E dequeue(); o(n)
E getFront(); o(1)
循环队列
原来出队是需要都往前移动一下, 循环队列只需要维护一下 front和tail两个值就行了 我们先指定一个标准 front == tail 队列为空 front == tail + 1 队列为满 (此时浪费了一个空间)
( tail + 1)%capacity == front 队列为满 (9 + 1) %10 == 0 (10+ 1) %10 == 1
package com.qcx.algo.day07.implqueue;
public class LoopQueue<E> implements Queue<E>{
private E[] data;
private int front, tail;
private int size;
public LoopQueue(int capacity){
data = (E[]) new Object[capacity + 1];
front = 0;
tail = 0;
size = 0;
}
public LoopQueue(){
this(10);
}
public int getCapacity(){
return data.length - 1;
}
@Override
public int getSize() {
return size;
}
@Override
public boolean isEmpty() {
return front==tail;
}
@Override
public void enqueue(E e) {
if ((tail + 1)%data.length == front)
resize(getCapacity()*2);
data[tail] = e;
tail = (tail + 1)%data.length;
size++;
}
private void resize(int newCapacity){
E[] newData = (E[]) new Object[newCapacity + 1];
for (int i = 0; i < size; i++) {
newData[i] = data[(i + front)% data.length];
}
data = newData;
front = 0;
tail = size;
}
@Override
public E dequeue() {
if (isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty LoopQueue");
E ret = data[front];
data[front] = null;
front = (front+1)% data.length;
size--;
if (size == getCapacity() / 4 && getCapacity()/2 !=0){
resize(getCapacity()/2);
}
return ret;
}
@Override
public E getFront() {
if (isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty LoopQueue");
return data[front];
}
@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append("Queue: ");
res.append("front [");
for (int i = front; i !=tail ; i = (i + 1)% data.length) {
res.append(data[i]);
if ((i + 1)% data.length != tail)
res.append(", ");
}
res.append("] tail");
return res.toString();
}
public static void main(String[] args) {
LoopQueue<Integer> loopQueue = new LoopQueue<>();
for (int i = 0; i < 10; i++) {
loopQueue.enqueue(i);
System.out.println(loopQueue);
if (i%3==2){
loopQueue.dequeue();
System.out.println(loopQueue);
}
}
}
}
测试
package com.qcx.algo.day07.implqueue;
import java.util.Random;
public class Main {
public static double testQueue(Queue<Integer> q, int opCount){
long startTime = System.nanoTime();
Random random = new Random();
for (int i = 0; i < opCount ; i++) {
q.enqueue(random.nextInt(Integer.MAX_VALUE));
}
for (int i = 0; i < opCount ; i++) {
q.dequeue();
}
long endTime = System.nanoTime();
return (endTime-startTime)/100000000.0;
}
public static void main(String[] args) {
int opCount = 100000;
Queue<Integer> arrayQueue = new ArrayQueue<>();
double time1 = testQueue(arrayQueue, opCount);
System.out.println("arrayQueue time = " + time1);
Queue<Integer> loopQueue = new LoopQueue<>();
double time2 = testQueue(loopQueue, opCount);
System.out.println("loopQueue time = " + time2);
}
}
|