队列概述
队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
–队尾(rear)——允许插入的一端
–队头(front)——允许删除的一端
队列特点:先进先出(FIFO)
队列的结构
如下图所示:
线性表的操作主要包括:
(2)判断是否为空
(3)元素的个数
(4)入队列
(5)出队列
(6)取对头元素
接口
由此,对队列的抽象数据类型定义Queue接口如下:
- package queue;
-
- public interface Queue {
-
-
-
- public void clear();
-
-
-
-
- public Object deQueue();
-
-
-
-
- public boolean isEmpty();
-
-
-
-
- public Object peek();
-
-
-
-
- public void push(Object obj);
-
-
-
-
- public int size();
- }
顺序循环队列
结构模型
•存在问题
设数组长度为M,则:
–当front=0,rear=M时,再有元素入队发生溢出——
真溢出
–当front!=0,rear=M时,再有元素入队发生溢出——
假溢出
•解决方案
–队首固定,每次出队剩余元素向下移动——浪费时间
–循环队列
»基本思想:把队列
设想成环形,让sq[0]接在sq[M-1]之后,若rear+1==M,则令rear=0;
源代码
- package queue;
-
-
-
-
-
- public class ArrayQueue implements Queue {
- private static int DEFAULT_SIZE = 10;
- private Object array[] = null;
- private int front, rear, count;
-
- public ArrayQueue() {
- array = new Object[DEFAULT_SIZE];
- front = rear = count = 0;
- }
-
- public boolean isEmpty() {
- if((rear == front) && (0 == count))
- return true;
- else
- return false;
- }
-
- public int size() {
- return count;
- }
-
- @Override
- public void push(Object obj) {
- if((rear == front) && (count>0))
- expand();
- array[rear] = obj;
- rear = (rear+1)%DEFAULT_SIZE;
- count ++;
- }
-
- @Override
- public Object deQueue() {
- if(0 == count) {
- throw new IllegalStateException("队列已空,无数据元素可出队列!");
- } else {
- Object obj = array[front];
- front = (front+1)%DEFAULT_SIZE;
- count --;
- return obj;
- }
- }
-
-
- @Override
- public Object peek() {
- if(0 == count) {
- throw new IllegalStateException("队列已空,无数据元素可出队列!");
- } else return array[front];
- }
-
- @Override
- public void clear() {
- for(int i=0; i<DEFAULT_SIZE; i++) {
- array[i] = null;
- }
- front = rear = count = 0;
- }
-
- private void expand() {
- Object newArray[] = new Object[2*DEFAULT_SIZE];
- for(int i=0; i<count; i++) {
- newArray[i] = array[(front+i)%DEFAULT_SIZE];
- }
- array = newArray;
- front = 0;
- rear = count;
- DEFAULT_SIZE = 2*DEFAULT_SIZE;
- }
-
- public String toString() {
- String str= "[";
- for(int i=0; i<count; i++) {
- str =str + array[(front+i)%DEFAULT_SIZE];
- str += ", ";
- }
- str += "]";
- return str;
- }
-
- }
链式队列
结构模型
设队首、队尾指针front和rear,front指向头结点,rear指向队尾
源代码
- package queue;
-
-
-
-
-
-
- class Node{
- Object data;
- Node next;
- public Node() {
- this(null);
- }
- public Node(Object data) {
- this.data = data;
- this.next = null;
- }
- }
-
-
-
-
-
- public class LinkQueue implements Queue{
- private Node front,rear;
- private int size;
- public LinkQueue() {
- front = rear = new Node();
- size = 0;
- }
- @Override
- public void clear() {
- front.next = null;
- rear = front;
- size = 0;
- }
-
- @Override
- public Object deQueue() {
- Node p = front.next;
- front.next = p.next;
- rear = p.next;
- size --;
- return p.data;
- }
-
- @Override
- public boolean isEmpty() {
- if(size == 0)
- return true;
- else
- return false;
- }
-
- @Override
- public Object peek() {
- return front.next.data;
- }
-
- @Override
- public void push(Object obj) {
- Node p = new Node(obj);
- rear.next = p;
- rear = p;
- size ++;
- }
-
- @Override
- public int size() {
- return size;
- }
-
- public String toString() {
- StringBuilder sb= new StringBuilder("[");
- Node p = front;
- while((p=p.next) != null) {
- sb.append(p.data + ", ");
- }
- sb.append("]");
- return sb.toString();
- }
- }
测试队列
- package queue;
-
- public class Test {
-
-
-
-
-
- public static void main(String[] args) {
-
- Queue queue = new ArrayQueue();
- for(int i=0; i<10; i++) {
- queue.push(i);
- }
- System.out.println(queue);
- Object obj1 = queue.deQueue();
- Object obj2 = queue.deQueue();
- System.out.println("count:" + queue.size() + " obj1:" + obj1 + " obj2:" + obj2);
- System.out.println(queue);
- System.out.println("peek:" + queue.peek());
-
-
- for(int i=0; i<12; i++) {
- queue.push(i+10);
- }
- }
- }
结果
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ]
count:8 obj1:0 obj2:1
[2, 3, 4, 5, 6, 7, 8, 9, ]
peek:2