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

数据结构(Java)——队列的实现

2015-11-16 19:19 393 查看
兴亡谁人定,胜败岂无凭——易中天《百家讲坛》

不得慕虚名而处实祸 ——曹操

1. 概述

队列是一种线性集合,其元素从一端加入,从另一端删除。因此队列是按照先进先出方式处理的,从队列中删除元素的次序与往队列里放置元素的的次序是一样的。

由于队列是一种线性集合,因此可以像处理栈一样,把队列实现成一种LinearNode对象的链表。

2. 队列ADT

队列核心功能的声明:

package ds.java.ch05.queueImpl;
/**
* @author LbZhang
* @version 创建时间:2015年11月16日 下午7:06:32
* @description 队列接口
*/
public interface QueueADT<T> {

public void enqueue(T elem);
public T dequeue();
public T first();

public boolean isEmpty();

public int size();
public String toString();

}


3. 链表实现队列

使用两个分别指向链表受元素、链表末元素的引用方便队列的链表实现。

package ds.java.ch05.queueImpl;
/**
* 结点类的声明
* @author MrLBZ
* @param <T>
*/
public class LinearNode<T> {
private LinearNode<T> next;
private T element;

public LinearNode() {
next = null;
element = null;
}

public LinearNode(T elem) {
next = null;
element = elem;
}

public LinearNode<T> getNext() {
return next;
}

public void setNext(LinearNode<T> node) {
next = node;
}

public T getElement() {
return element;
}

public void setElement(T elem) {
element = elem;
}
}


package ds.java.ch05.queueImpl;

public class EmptyCollectionException extends RuntimeException
{
/**
* Sets up this exception with an appropriate message.
*/
public EmptyCollectionException (String collection)
{
super ("The " + collection + " is empty.");
}
}


package ds.java.ch05.queueImpl;

/**
* @author LbZhang
* @version 创建时间:2015年11月16日 下午7:30:59
* @description 链表实现队列
*/
public class LinkedQueue<T> implements QueueADT<T> {

private int count;
private LinearNode<T> head, tail;

// 首尾声明

/**
* 初始化队列
*/
public LinkedQueue() {
count = 0;
head = tail = null;

}

@Override
public void enqueue(T elem) {
LinearNode<T> node = new LinearNode<T>(elem);
if (isEmpty()) {// /如果是空的话初始化头结点
head = node;
} else {
tail.setNext(node);
}
tail = node;// /新结点的next不需要显式的设置 因为在new一个新结点的时候已经设置完毕
count++;
}

@Override
public T dequeue() throws EmptyCollectionException{
if (isEmpty()) {
throw new EmptyCollectionException("queue");
}
T result = head.getElement();
head = head.getNext();
count--;
if (isEmpty()) {
tail = null;// /如果栈变成了空栈
}
return result;
}

@Override
public T first() throws EmptyCollectionException{
if (isEmpty())
throw new EmptyCollectionException("queue");

return head.getElement();
}

@Override
public boolean isEmpty() {

return (count == 0);
}

@Override
public int size() {

return count;
}

@Override
public String toString() {
String result = "";
LinearNode<T> current = head;

while (current != null) {
result = result + (current.getElement()).toString() + "\n";
current = current.getNext();
}

return result;
}
}


4. 数组实现队列

把数组看作是环形的,可以除去在队列的数组实现中把元素移位的需要。

package ds.java.ch05.queueImpl;

/**
* @author LbZhang
* @version 创建时间:2015年11月16日 下午10:14:12
* @description 环形数组 可以除去在队列的数组实现中元素移位的需要
*/
public class CircularArrayQueue<T> implements QueueADT<T> {

private final static int DEFAULT_CAPACITY = 100;
private int front, rear, count;
private T[] queue;// 数组队列

public CircularArrayQueue() {
this(DEFAULT_CAPACITY);

}

public CircularArrayQueue(int initc) {

front = rear = count = 0;
queue = (T[]) (new Object[initc]);
}

@Override
public void enqueue(T elem) {
if (size() == queue.length) {
expandCapacity();
}
queue[rear] = elem;
rear = (rear + 1) % queue.length;// 设置尾坐标
count++;
}

private void expandCapacity() {
// /开辟数组
T[] larger = (T[]) (new Object[queue.length * 2]);

// 复制数组
for (int scan = 0; scan < count; scan++) {
larger[scan] = queue[front];// 从front开始复制
front = (front + 1) % queue.length;
}

// /重置首尾结点
front = 0;
rear = count;

queue = larger;

}

/**
* 出队列
*/
@Override
public T dequeue() {
if (isEmpty())
throw new EmptyCollectionException("queue");

T result = queue[front];// 获取front的结点内容
queue[front] = null;// 置空front结点
front = (front + 1) % queue.length;// front后移
count--;
return result;
}

@Override
public T first() {
if (isEmpty())
throw new EmptyCollectionException("queue");

T result = queue[front];// 获取front的结点内容
return result;
}

@Override
public boolean isEmpty() {
return (count == 0);
}

@Override
public int size() {
return count;
}

@Override
public String toString() {
String result = "";
int scan = 0;

while (scan < count) {
if (queue[scan] != null) {
result += queue[scan].toString() + "\n";
}
scan++;
}

return result;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 队列 Java