数据结构-队列
2017-01-21 18:47
162 查看
队列
队列(queue)简称队,它同堆栈一样,也是一种运算受限的线性表,其限制是仅允许在表的一端进行插入,而在表的另一端进行删除。在队列中把插入数据元素的一端称为队尾(rear),删除数据元素的一端称为队首(front)。向队尾插入元素称为进队或入队,新元素入队后成为新的队尾元素;从队列中删除元素称为离队或出队,元素出队后,其后续元素成为新的队首元素。
由于队列的插入和删除操作分别在队尾和队首进行,每个元素必然按照进入的次序离队,也就是说先进队的元素必然先离队,所以称队列为先进先出表(First In First Out,简称 FIFO)。队列结构与日常生活中排队等候服务的模型是一致的,早进入队列的人,早得 到服务并从队首离开;后到来的人只能排在队列的后,后得到服务并后离开。
Queue 接口
代码实现如下:package com.wjy.Data_Structure.queue; public interface Queue { /** * 返回队列的大小 * * @return */ public int getSize(); /** * 判断队列是否为空 * * @return */ public boolean isEmpty(); /** * 数据元素 e 入队 * * @param e */ public void enqueue(Object e); /** * 队首元素出队 * * @return */ public Object dequeue() throws QueueEmptyException; /** * 取队首元素 * * @return */ public Object peek() throws QueueEmptyException; }
异常类定义
package com.wjy.Data_Structure.queue; public class QueueEmptyException extends RuntimeException { private static final long serialVersionUID = 1L; public QueueEmptyException(String err) { super(err); } }
1.队列的顺序存储实现
在队列的顺序存储实现中,我们可以将队列当作一般的表用数组加以实现,但这样做的效果并不好,当我们删除队首元素时候必须将数组中所有其他元素都向前移动一个位置。为了提高运算的效率,设想数组 A[0.. capacity-1]中的单元不是排成一行,而是围成一个圆环,即 A[0]接在 A[capacity-1]的后面。这种意义下的数组称为循环数组,如图所示:
代码实现如下:
package com.wjy.Data_Structure.queue; public class QueueArray implements Queue { private static final int CAP = 7; // 队列默认大小 private Object[] elements; // 数据元素数组 private int capacity; // 数组的大小 private int front; // 队首指针,指向队首 private int rear; // 队尾指针,指向队尾后一个位置 public QueueArray() { this(CAP); } public QueueArray(int cap) { capacity = cap + 1; elements = new Object[capacity]; front = rear = 0; } private void expandSpace() { Object[] a = new Object[elements.length * 2]; int i = front, j = 0; while (i != rear) { a[j++] = elements[i]; i = (i + 1) % capacity; } elements = a; capacity = elements.length; front = 0; rear = j; } @Override public int getSize() { return (rear - front + capacity) % capacity; } @Override public boolean isEmpty() { return front == rear; } @Override public void enqueue(Object e) { if (getSize() == capacity - 1) expandSpace(); elements[rear] = e; rear = (rear + 1) % capacity; } @Override public Object dequeue() throws QueueEmptyException { if (isEmpty()) throw new QueueEmptyException("错误:队列为空"); Object obj = elements[front]; elements[front] = null; front = (front + 1) % capacity; return obj; } @Override public Object peek() throws QueueEmptyException { if (isEmpty()) throw new QueueEmptyException("错误:队列为空"); return elements[front]; } }
2.队列的链式存储实现
队列的链式存储可以使用单链表来实现。这里采用带头结点的单链表结构。如图所示。队首指针指向队首元素的前一个结点,即始终指向链表空的头结点,队尾指针指向队列当前队尾元素所在的结点。当队列为空时,队首指针与队尾指针均指向空的头结点。
代码实现如下:
package com.wjy.Data_Structure.queue; import com.wjy.Data_Structure.linearlist.common.SLNode; public class QueueSLinked implements Queue { private SLNode front; // 队首指针 private SLNode rear; // 队尾指针 private int size; // 元素个数 public QueueSLinked() { this.front = new SLNode(); this.rear = front; this.size = 0; } @Override public int getSize() { return size; } @Override public boolean isEmpty() { return size == 0; } @Override public void enqueue(Object e) { SLNode p = new SLNode(e, null); rear.setNext(p); rear = p; size++; } @Override public Object dequeue() throws QueueEmptyException { if (size < 1) throw new QueueEmptyException("错误:队列为空"); SLNode p = front.getNext(); front.setNext(p.getNext()); size--; if (size < 1) rear = front; // 如果队列为空,rear指向头结点 return p.getData(); } @Override public Object peek() throws QueueEmptyException { if (size < 1) throw new QueueEmptyException("错误:队列为空"); return front.getNext().getData(); } }
相关文章推荐
- 数据结构3.1——队列
- 【数据结构】非循环队列
- 数据结构-->队列的链式实现 ADT
- C语言数据结构队列
- 数据结构-队列
- 基于JavaScript的数据结构队列动画实现一
- 数据结构--用C实现链式队列
- 数据结构 用栈和队列判断回文数
- 数据结构(ZKNU OJ)猴子选大王(循环队列解法)
- 动手实现 数据结构 之 “队列”
- 《数据结构》实验三: 栈和队列实验
- 【图解数据结构】 栈&队列
- 数据结构学习(6):队列
- 【数据结构】二叉树中包含的【堆栈、链表、队列】
- 《数据结构》实验三:栈和队列实验报告
- C语言数据结构链表队列的实现
- 数据结构_队列
- 数据结构---->队列
- java数据结构 栈和队列
- 【算法和数据结构】线性表(四)用两个栈来实现队列(C++实现)