1. 程式人生 > >資料結構 JAVA描述(三) 佇列 + 棧與佇列的比較

資料結構 JAVA描述(三) 佇列 + 棧與佇列的比較

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("此佇列為空");
        }
    }
}

相同點:

  1. 都是線性結構,即元素之間具有“一對一”的邏輯關係
  2. 插入操作都限制在表尾
  3. 都可在順序儲存結構和鏈式儲存結構實現
  4. 在時間和空間代價上,插入與刪除都需要常數時間
  5. 多鏈棧和多鏈佇列的管理模式可以相同

不同點:

  1. 刪除元素位置不同。棧的控制在表尾,佇列的控制在表頭。
  2. 應用場合不同。棧:如遞迴呼叫現場資訊、計算中間結果、引數值的儲存;圖與樹的深度優先搜尋遍歷。 佇列:如訊息緩衝器的管理,作業系統中對記憶體、印表機等各種資源進行管理,優先順序的服務請求,圖和樹的廣度搜索遍歷
  3. 順序棧可實現多棧空間共享,而順序佇列則不同。如可使用兩個棧共享一片陣列空間。