这一篇是整个专题的第四篇,前几篇讲了堆栈,链表相关,与它们一样,队列的性质和前者相似,同时也拥有线性结构和离散结构两种,本篇就详细讲讲队列吧
顺序队列
顺序队列的实现同样包含两方面
一、数据集合
队列的数据集合可以表示为a0,a1,…,an-1,每个数据元素的数据类型可以是任意的类型。
二、操作集合
(1)入队列append(obj):把数据元素obj插入队尾。
(2)出队列delete():把队头数据元素删除并由函数返回。
(3)取队头数据元素getFront():取队头数据元素并由函数返回。
(4)非空否isEmpty():非空否。若队列非空,则函数返回false,否则函数返回true。
根据操作集合我们设计出队列的功能接口类Queue_,离散队列设计同样用到该接口
public interface Queue_ {
void append(Object object)throws Exception;
Object delete()throws Exception;
Object getFront()throws Exception;
boolean isEmpty();
}
功能逻辑类
这里有个问题,就是队列会产生假溢出;
假溢出是由于队尾rear的值和队头front的值不能由所定义数组下界值自动转为数组上界值而产生的。因此,解决的方法是把顺序队列所使用的存储空间构造成一个逻辑上首尾相连的循环队列( Circular Queue)。
当rear和front达到maxSize-1后,再加1就自动到0。这样,就不会出现顺序队列数组的头部已空出许多存储空间,但队尾却因数组下标越界而引起溢出的假溢出问题。
为此,解决这个问题的方法有三种:
(1)设计一个布尔变量以判断队列的空和满;
添加一个标志位。设标志位为tag,初始时置tag=0;每当入队列操作成功就置tag=1;每当出队列操作成功就置tag=0。则队列空的判断条件为:
rear == front && tag==0
队列满的判断条件为:
rear = = front && tag= =1
(2)少用一个存储空间。
当少用一个存储空间时,以队尾rear加1等于队头 front为队列满的判断条件,即队列满的判断条件此时为:
(rear + 1) % maxSize == front
队列空的判断条件仍然为:
rear = = front
(3)设计一个计数器,统计队列中得元素个数。
添加一个计数器。设计数器为count,初始时置count=0;每当入队列操作成功就使count加1;每当出队列操作成功就使count减1。这样,该计数器不仅具有计数功能,而且还具有像标志位一样的标志作用,则此时队列空的判断条件为:
count == 0
队列满的判断条件为:
count > 0 && rear == front
具体在code里面体现
/**
* 顺序队列
* @author robert
*
*/
public class CircularQueue_ implements Queue_ {
public static final int defaultsize = 10;
int front;//对头
int rear;//对尾
int maxsize;//最大长度
int count;
Object[] quere;
public CircularQueue_() {
init(defaultsize);
}
public CircularQueue_(int size) {
init(size);
}
public void init(int size) {
this.maxsize = size;
this.front = this.rear = 0;
this.count = 0;
this.quere = new Object[size];
}
@Override
public void append(Object object) throws Exception {
if (count > 0 && front == rear) {
throw new Exception("队列已满");
}
quere[rear] = object;
rear += 1 % maxsize;// 防止假溢出
count++;
}
@Override
public Object delete() throws Exception {
if (isEmpty()) {
throw new Exception("队列为空");
}
Object object = quere[front];
front = front += 1 % maxsize;
count--;
return object;
}
@Override
public Object getFront() throws Exception {
if (!isEmpty()) {
return quere[front];
} else {
return null;
}
}
@Override
public boolean isEmpty() {
return count == 0;
}
}
测试类Test
public class Test_quere {
public static void main(String[] args) throws Exception {
CircularQueue_ queue = new CircularQueue_();
queue.append("a");
queue.append("b");
queue.append("c");
queue.append("d");
queue.append("e");
queue.append("f");
queue.delete();
//queue.delete();
queue.append("g");
while (!queue.isEmpty()) {
System.out.println(queue.delete());
}
}
}
结果:
离散队列
这里不多说了,直接上code
接口Queue_
public interface Queue_ {
void append(Object object)throws Exception;
Object delete()throws Exception;
Object getFront()throws Exception;
boolean isEmpty();
}
抽象数据类型结点类
public class QueueNode_ {
public Object elenment;
public QueueNode_ next;
public QueueNode_(QueueNode_ next) {
super();
this.next = next;
}
/**
*
* elenment:数据
* next:指针
*
* @param elenment
* @param next
*
*/
public QueueNode_(Object elenment, QueueNode_ next) {
super();
this.elenment = elenment;
this.next = next;
}
public Object getElenment() {
return elenment;
}
public void setElenment(Object elenment) {
this.elenment = elenment;
}
public QueueNode_ getNext() {
return next;
}
public void setNext(QueueNode_ next) {
this.next = next;
}
@Override
public String toString() {
return "ListNode_ [elenment=" + elenment + ", next=" + next + "]";
}
}
队列逻辑类
/**
* 链式队列
*
* @author robert
*
*/
public class LinkQueue_ implements Queue_ {
int mcount;
QueueNode_ front;
QueueNode_ rear;
public LinkQueue_() {
this.front = this.rear = null;
this.mcount = 0;
}
@Override
public void append(Object object) throws Exception {
QueueNode_ node_ = new QueueNode_(object, null);
if (rear != null) {
node_.next = node_;
}
rear = node_;
if (front == null) {
front = node_;
}
mcount++;
}
@Override
public Object delete() throws Exception {
if(isEmpty()){
throw new Exception("");
}
QueueNode_ node_ = front;
front = front.next;
mcount--;
return node_.getElenment();
}
@Override
public Object getFront() throws Exception {
if (!isEmpty()) {
return front.getElenment();
} else {
return null;
}
}
@Override
public boolean isEmpty() {
return mcount == 0;
}
}
测试类Test
public class Test_linkqueue {
public static boolean isHuiWen(String str) throws Exception {
int n = str.length();
LinkStack_ stack_ = new LinkStack_();
LinkQueue_ queue_ = new LinkQueue_();
for (int i = 0; i < n; i++) {
stack_.push(str.subSequence(i, i + 1));
queue_.append(str.subSequence(i, i + 1));
}
while (!queue_.isEmpty() && !!queue_.isEmpty()) {
if (stack_.pop().equals(queue_.delete())) {
return true;
}
}
return true;
}
}
队列就说到这里,下一篇,讲串结构,也是本专题的完结篇