隊列基本概念1 數據集合
隊列的數據集合可以表示爲a0,a1,…,an-1,每個數據元素的數據類型可以是任意的類型。
2 操作集合
(1)入隊列append(obj):把數據元素obj插入隊尾。
(2)出隊列delete():把隊頭數據元素刪除並由函數返回。
(3)取隊頭數據元素getFront():取隊頭數據元素並由函數返回。
(4)非空否isEmpty():非空否。若隊列非空,則函數返回false,否則函數返回true。
隊列抽象數據類型的Java接口定義如下:
public interface Queue{
public voidappend(Object obj) throws Exception;
public Object delete()throws Exception;
public ObjectgetFront() throws Exception;
public booleanisEmpty();
}
順序隊列
(1)設計一個布爾變量以判斷隊列的空和滿;
(2)少用一個存儲空間。
(3)設計一個計數器,統計隊列中得元素個數。
1)設計一個布爾變量以判斷隊列的空和滿;
添加一個標誌位。設標誌位爲tag,初始時置tag=0;每當入隊列操作成功就置tag=1;每當出隊列操作成功就置tag=0。則隊列空的判斷條件爲:
rear == front&& tag==0
隊列滿的判斷條件爲:
rear = = front&& tag= =1
當少用一個存儲空間時,以隊尾rear加1等於隊頭 front爲隊列滿的判斷條件,即隊列滿的判斷條件此時爲:
(rear + 1) % maxSize== front
隊列空的判斷條件仍然爲:
rear = = front
3)設計一個計數器,統計隊列中得元素個數。
添加一個計數器。設計數器爲count,初始時置count=0;每當入隊列操作成功就使count加1;每當出隊列操作成功就使count減1。這樣,該計數器不僅具有計數功能,而且還具有像標誌位一樣的標誌作用,則此時隊列空的判斷條件爲:
count == 0
隊列滿的判斷條件爲:
count > 0&& rear == front
順序循環隊列的實現
//隊列接口 public interface Queue { //入隊 public void append(Object obj) throws Exception; //出隊 public Object delete() throws Exception; //獲得隊頭元素 public Object getFront() throws Exception; //判斷對列是否爲空 public boolean isEmpty(); }
//循環順序隊列
public class CircleSequenceQueue implements Queue{
static final int defaultSize = 10; //默認隊列的長度
int front; //隊頭
int rear; //隊尾
int count; //統計元素個數的計數器
int maxSize; //隊的最大長度
Object[] queue; //隊列
public CircleSequenceQueue()
{
init(defaultSize);
}
public CircleSequenceQueue(int size)
{
init(size);
}
public void init(int size)
{
maxSize = size;
front=rear=0;
count=0;
queue = new Object[size];
}
@Override
public void append(Object obj) throws Exception {
// TODO Auto-generated method stub
if(count>0&&front==rear)
{
throw new Exception("隊列已滿!");
}
queue[rear]=obj;
rear=(rear+1)%maxSize;
count++;
}
@Override
public Object delete() throws Exception {
// TODO Auto-generated method stub
if(isEmpty())
{
throw new Exception("隊列爲空!");
}
Object obj = queue[front];
front = (front+1)%maxSize;
count--;
return obj;
}
@Override
public Object getFront() throws Exception {
// TODO Auto-generated method stub
if(!isEmpty())
{
return queue[front];
}
else
{
return null;
}
}
@Override
public boolean isEmpty() {
// TODO Auto-generated method stub
return count==0;
}
}
循環隊列應用
//賣票者
public class Consumer implements Runnable {
WindowQueue queue ;
public Consumer(WindowQueue queue)
{
this.queue = queue;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(queue.isAlive)
{
try
{
queue.consumer();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
//買票者
public class Producer implements Runnable {
WindowQueue queue ;
public Producer(WindowQueue queue)
{
this.queue = queue;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(queue.num<100)
{
try
{
queue.producer();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
//賣票窗口
public class WindowQueue {
//賣票的隊列
int maxSize =10;
CircleSequenceQueue queue = new CircleSequenceQueue(maxSize);
int num=0; //統計賣票的數量,一天最多賣100張票。
boolean isAlive = true; //判斷是否繼續賣票。
//排隊買票
public synchronized void producer() throws Exception
{
if(queue.count < maxSize)
{
queue.append(num++); //等待買票的數量加1
System.out.println("第"+num+"個客戶排隊等待買票!");
this.notifyAll();//喚醒賣票的線程
}
else
{
try
{
System.out.println("隊列已滿...請等待!");
this.wait();//隊列滿時,排隊買票線程等待。
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
//賣票
public synchronized void consumer() throws Exception
{
if(queue.count > 0)
{
Object obj = queue.delete();
int temp = Integer.parseInt(obj.toString());
System.out.println("第"+(temp+1)+"個客戶買到票離開隊列!");
//如果當前隊列爲空,並且賣出票的數量大於等於100,說明賣票結束
if(queue.isEmpty()&&this.num>=100)
{
this.isAlive = false;
}
this.notifyAll(); //喚醒排隊買票的線程。
}
else
{
try
{
System.out.println("隊列已空...請等待!");
this.wait();//隊列空時,賣票線程等待。
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
}
}
public class Test {
/**
* @param args
*/
public static void main(String[] args)throws Exception {
WindowQueue queue = new WindowQueue();
Producer p = new Producer(queue);//注意一定要傳同一個窗口對象
Consumer c = new Consumer(queue);
//排隊買票線程
Thread pThread = new Thread(p);
//賣票線程
Thread cThread = new Thread(c);
pThread.start(); //開始排隊買票
cThread.start(); //開始賣票
}
}