您的位置:首页 > 理论基础 > 数据结构算法

【数据结构】队列(顺序队列、链队列)的JAVA代码实现

2018-03-28 20:35 671 查看
队列(queue)是一种特殊的线性表,只允许在表的一端进行插入操作而在另一端进行删除的线性表。进行插入操作的端称为队尾,进行删除操作的一端称为队头。队列中没有数据元素时称为空队列。
队列的操作是按照先进先出(first in first out)或后进后出(last in last out)的原则进行的。因此,队列又被称为FIFO表。它的实现方式主要有顺序队列、链队列两种

队列的抽象数据模型

数据元素:可以为任意类型,只要同属于一种数据类型即可;
数据关系:数据元素之间呈线性关系;
数据操作:对队列的基本操作定义在IQueue中,代码如下:
public interface IQueue<E> {
boolean enqueue(E item); //入队列操作
E dequeue(); //出队列操作
E peek(); //取对头元素
int size(); //求队列的长度
boolean isEmpty(); //判断队列是否为空
boolean isFull(); //判断队列是否为满
}

顺序队列

4000
用一片连续的存储空间来存储队列中的数据元素,这样的队列称为顺序队列。类似于顺序栈,用一维数组来存放顺序队列中的数据元素。队头设置在最近一个已经离开队列的元素所占的位置,用front表示;队尾设置在最近一个进行入队列的元素位置,用rear表示。front和rear随着插入和删除而变化。当队列为空时,front=rear=-1。
当有数据元素入队列时,队尾指示器rear加1,当有数据元素出队列时,队头指示器front加1。当front=rear时,表示队列为空,当队尾指示器rear达到数组的上限处而front为-1时,队列为满。队尾指示器rear的值大于对头指示器front的值,队列中的元素个数可以由rear-front求得。
但是!有时候,队列未满但再有一个元素入队就会出现溢出。但事实上队列并未满,还有空闲空间,这种情况成为“假溢出”。这是由于队列“队尾入队,队头出”的操作原则造成的。解决假溢出的方法是将顺序队列看成是首尾相接的循环结构,首尾指示器的关系不变,这种队列叫循环顺序队列。
当队尾指示器rear达到数组的上限是,如果还有数据元素入队并且数组的第0个空间空闲时,队尾指示器rear指向数组的0端。所以,队尾指示器的加1操作修改为:rear=(rear+1)%maxsize
队头指示器的操作也是如此。当队头指示器front达到数组的上限时,如果还有数据元素出队,队头指示器指向数组的0端。所以,队头指示器的加1操作修改为:front=(front+1)%maxsize
这样又有一个问题,队满和队空的时候,都有rear=front。为了解决这个问题的方法是一般少用一个空间,所以判断队空的条件是rear=front,判断队满的条件是(rear+1)%maxsize=front,与此同时,循环队列中数据元素的个数是(rear-front+maxsize)%maxsize。此时,front表示队头,rear表示队尾,两者的范围都是0-maxsize-1。public class SeqQueue<E> implements IQueue<E> {
private int maxsize; //队列的容量
private E[] data; // 存储循环顺序队列中的数据元素
private int front; // 指示最近一个己经离开队列的元素所占的位置
private int rear; // 指示最近一个进行入队列的元素的位置
//初始化队列
@SuppressWarnings("unchecked")
public SeqQueue(Class<E> type, int maxsize) {
data = (E[]) Array.newInstance(type, maxsize);
this.maxsize = maxsize;
front = rear = -1;
}
//入队列操作
public boolean enqueue(E item) {
if (!isFull()) {
rear = (rear + 1) % maxsize;
data[rear] = item;
return true;
} else
return false;
}
//出队列操作
public E dequeue() {
if (!isEmpty()) {
front = (front + 1) % maxsize;
return data[front];
} else
return null;

}

//取对头元素
public E peek() {
if (!isEmpty()) {
return data[(front + 1) % maxsize];
} else
return null;
}
//求队列的长度
public int size() {

return (rear - front + maxsize) % maxsize;
}
// 判断队列是否为空
public boolean isEmpty() {
if (front == rear) {
return true;
} else {
return false;
}
}
// 判断循环顺序队列是否为满
public boolean isFull() {
if ((front == -1 && rear == maxsize - 1)
|| (rear + 1) % maxsize == front) {
return true;
} else {
return false;
}
}
}

链队列

用链式存储结构来存储队列中的数据元素,这样的队列称为链队列。同链栈一样,链队列一般也采用单链表来表示,设队头指示器为front,队尾指示器rear。class QueueNode<E>
{
private E data; // 数据域
private QueueNode<E> next; // 引用域
//构造函数
public QueueNode(){}
public QueueNode(E data) {
this.data = data;
}
public QueueNode(E data, QueueNode<E> next) {
this.data = data;
this.next = next;
}
//数据域get属性
public E getData() {
return data;
}
//数据域set属性
public void setData(E data) {
this.data = data;
}
//引用域get属性
public QueueNode<E> getNext() {
return next;
}
//引用域get属性
public void setNext(QueueNode<E> next) {
this.next = next;
}
}
public class LinkQueue<E> implements IQueue<E> {
private QueueNode<E> front; // 队列头指示器
private QueueNode<E> rear; // 队列尾指示器
private int maxsize; // 队列的容量,假如为0,不限容量
private int size; // 队列数据元素个数

// 初始化链队列
public LinkQueue() {
front = rear = null;
size = 0;
maxsize = 0;
}

// 初始化限容量的链队列
public LinkQueue(int maxsize) {
super();
this.maxsize = maxsize;
}

// 入队列操作
public boolean enqueue(E item) {
QueueNode<E> newnode = new QueueNode<E>(item);
if (!isFull()) {
if (isEmpty()) {
front = newnode;
rear = newnode;
} else {
rear.setNext(newnode);
rear = newnode;
}
++size;
return true;
} else
return false;
}

// 出队列操作
public E dequeue() {
if (isEmpty())
return null;
QueueNode<E> node = front;
front = front.getNext();
if (front == null) {
rear = null;
}
--size;
return node.getData();

}

// 取对头元素
public E peek() {
if (!isEmpty()) {
return front.getData();
} else
return null;
}

// 求队列的长度
public int size() {
// TODO Auto-generated method stub
return size;
}

// 判断队列是否为空
public boolean isEmpty() {
if ((front == rear) && (size == 0)) {
return true;
} else {
return false;
}
}

// 判断队列是否为满
public boolean isFull() {
if (maxsize != 0 && size == maxsize) {
return true;
} else {
return false;
}
}
}

总结与分析

位于java.util.Queue的接口拓展了java.util.Collection接口,定义了队列存取元素的基本方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐