資料結構 JAVA描述(三) 佇列 + 棧與佇列的比較
阿新 • • 發佈:2019-02-19
package Queue;
/**
* @description 佇列的抽象資料型別描述
*
* @date 2015年12月29日
*/
public interface IQueue {
public void clear();
public boolean isEmpty();
public int length();
public Object peek();
public void offer(Object x) throws Exception;
public Object poll();
public void display();
}
package Queue;
/**
* @description 迴圈順序佇列,少用一個儲存單元作為隊空和隊滿的判斷依據
*
* @date 2015年12月29日
*/
public class CircleSqQueue implements IQueue {
private Object[] queueElem; //佇列儲存空間
private int front; //隊頭,佇列非空則指向隊頭元素
private int rear; //隊尾,佇列非空則指向隊尾元素
public CircleSqQueue (int maxSize) {
front = rear = 0;
queueElem = new Object[maxSize];
}
public void clear() {
front = rear = 0;
}
public boolean isEmpty() {
return rear == front;
}
public int length() {
// rear可能小於front
return (rear - front + queueElem.length) % queueElem.length;
}
/**
* @description 讀取隊首元素
* @return
* @author liuquan
* @date 2015年12月29日
*/
public Object peek() {
// 判斷佇列是否為空
if (front == rear)
return null;
else
return queueElem[front];
}
/**
* @description 入隊
* @param x
* @throws Exception
* @author liuquan
* @date 2015年12月29日
*/
public void offer(Object x) throws Exception {
// 判斷佇列是否已滿
if ((rear + 1) % queueElem.length == front)
throw new Exception("佇列已滿");
else {
queueElem[rear] = x;
rear = (rear + 1) % queueElem.length;
}
}
/**
* @description 出隊
* @return
* @author liuquan
* @date 2015年12月29日
*/
public Object poll() {
// 判斷佇列是否為空
if (front == rear)
return null;
else {
Object t = queueElem[front];
front = (front + 1) % queueElem.length;
return t;
}
}
public void display() {
if (!isEmpty()) {
for (int i = front; i != rear; i = (i + 1) % queueElem.length)
System.out.print(queueElem[i].toString() + " ");
}
else {
System.out.println("此佇列為空");
}
}
}
Node:
package Queue;
/**
* @description 結點結構 在很多資料結構中可以通用的
*
* @date 2015年12月29日
*/
public class Node {
private Object data;
private Node next;
public Node() {
this(null, null);
}
public Node(Object data) {
this(data, null);
}
public Node(Object data, Node next) {
this.data = data;
this.next = next;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
package Queue;
/**
* @description 鏈佇列的結構描述
*
* @date 2015年12月29日
*/
public class LinkQueue implements IQueue {
private Node front; // 隊首指標
private Node rear; // 隊尾指標
public LinkQueue() {
front = rear = null;
}
public void clear() {
front = rear = null;
}
public boolean isEmpty() {
return front == null;
}
public int length() {
int length = 0;
if (!isEmpty()) { // 佇列非空
Node p = front;
while (p != null) {
p = p.getNext();
++length;
}
}
return length;
}
/**
* @description 取隊首元素
* @return
* @author liuquan
* @date 2015年12月29日
*/
public Object peek() {
if (front != null) // 佇列非空
return front.getData();
else
return null;
}
/**
* @description 入隊
* @param x
* @throws Exception
* @author liuquan
* @date 2015年12月29日
*/
public void offer(Object x) throws Exception {
Node p = new Node(x);
if (front != null) {
rear.setNext(p);
rear = p;
}
else
front = rear = p;
}
/**
* @description 出隊
* @return
* @author liuquan
* @date 2015年12月29日
*/
public Object poll() {
if (front != null) {
Node p = front;
front = front.getNext();
return p.getData();
}
else
return null;
}
public void display() {
if (!isEmpty()) {
Node p = front;
while (p != rear.getNext()) {
System.out.print(p.getData() + " ");
p = p.getNext();
}
}
else {
System.out.println("此佇列為空");
}
}
}
package Queue;
/**
* @description 優先順序佇列的結點結構
*
* @date 2015年12月29日
*/
class PriorityQData {
private Object elem; // 結點的值
private int priority; // 結點的優先順序
public PriorityQData(Object elem, int priority) {
this.elem = elem;
this.priority = priority;
}
public Object getElem() {
return elem;
}
public void setElem(Object elem) {
this.elem = elem;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
/**
* @description 優先順序鏈佇列結構
*
* @date 2015年12月29日
*/
public class PriorityQueue implements IQueue {
private Node front;
private Node rear;
public PriorityQueue() {
front = rear = null;
}
public void clear() {
front = rear = null;
}
public boolean isEmpty() {
return front == rear;
}
public int length() {
int length = 0;
if (!isEmpty()) {
Node p = front;
while (p != null) {
p = p.getNext();
++length;
}
}
return length;
}
public Object peek() {
if (front != null)
return front.getData();
else
return null;
}
/**
* @description 入隊 按優先順序由大到小排列( 數值越小優先順序越大)
* @param x
* @throws Exception
* @author liuquan
* @date 2015年12月29日
*/
public void offer(Object x) throws Exception {
PriorityQData pn = (PriorityQData) x;
Node s = new Node(pn);
if (front == null)
front = rear = s;
else {
// 在普通情況下 新插入的結點x在q與p之間
Node p = front, q = front;
while (p != null && pn.getPriority() >= ((PriorityQData) p.getData()).getPriority()) {
q = p;
p = p.getNext();
}
// 表示遍歷到了隊尾 (q指向隊尾 p指向null)
if (p == null) {
rear.setNext(s);
rear = s;
}
// 表示p的優先順序大於首結點的優先順序
else if (p == front) {
s.setNext(front);
front = s;
}
else {
q.setNext(s);
s.setNext(p);
}
}
}
/**
* @description 出隊
* @return
* @author liuquan
* @date 2015年12月29日
*/
public Object poll() {
if (front != null) {
Node p = front;
front = front.getNext();
return p.getData();
}
else
return null;
}
public void display() {
if (!isEmpty()) {
Node p = front;
while (p != rear.getNext()) {
PriorityQData t = (PriorityQData) p.getData();
System.out.println(t.getElem() + " " + t.getPriority());
p = p.getNext();
}
} else {
System.out.println("此佇列為空");
}
}
}
相同點:
- 都是線性結構,即元素之間具有“一對一”的邏輯關係
- 插入操作都限制在表尾
- 都可在順序儲存結構和鏈式儲存結構實現
- 在時間和空間代價上,插入與刪除都需要常數時間
- 多鏈棧和多鏈佇列的管理模式可以相同
不同點:
- 刪除元素位置不同。棧的控制在表尾,佇列的控制在表頭。
- 應用場合不同。棧:如遞迴呼叫現場資訊、計算中間結果、引數值的儲存;圖與樹的深度優先搜尋遍歷。 佇列:如訊息緩衝器的管理,作業系統中對記憶體、印表機等各種資源進行管理,優先順序的服務請求,圖和樹的廣度搜索遍歷
- 順序棧可實現多棧空間共享,而順序佇列則不同。如可使用兩個棧共享一片陣列空間。