數據結構循環順序隊列、鏈隊和優先級隊列的Java實現

本篇博文用java實現了數據結構中的循環順序隊列、鏈隊和優先級隊列
源碼分享在github:數據結構,當然你也可以從下面的代碼片中獲取

1.隊列接口 IQueue .java

/*
* 隊列接口
* */
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();//出隊
}

2.循環順序隊列 CircleSqQueue.java

/*
* 循環順序隊列
* 解決假溢出問題
* */

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];
    }

    //隊列置空
    @Override
    public void clear() {
        front = rear = 0;
    }

    //判斷隊列是否爲空
    @Override
    public boolean isEmpty() {
        return front==rear;
    }

    //求隊列長度
    @Override
    public int length() {
        return (rear-front+queueElem.length)%queueElem.length;//rear-front有可能是負數,則需要+queueElem.length
    }

    //讀取隊首的元素
    @Override
    public Object peek() {
        if(front == rear){
            return null;
        }else{
            return queueElem[front];
        }
    }

    //入隊
    @Override
    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;

    }

    //出隊
    @Override
    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("此隊列爲空");
        }
    }
}

3.鏈隊 LinkQueue.java

public class LinkQueue implements IQueue {
    private Node front;//隊首指針
    private Node rear;//隊尾指針

    //構造函數
    public LinkQueue() {
        front = rear = null;
    }

    //隊列置空
    @Override
    public void clear() {
        front = rear = null;
    }

    //判空
    @Override
    public boolean isEmpty() {
        return front==null;
    }

    //求隊列長度
    @Override
    public int length() {
        Node p = front;
        int length = 0;
        while(p!=null){
            p = p.next;
            ++length;
        }
        return length;
    }

    //取隊首元素
    @Override
    public Object peek() {
        if(front!=null)
            return front.data;
        else
            return null;
    }

    //入隊
    @Override
    public void offer(Object x) throws Exception {
        Node p = new Node(x);
        if(front!=null){
            rear.next = p;
            rear = p;
        }else{
            front = rear = p;
        }
    }

    //出隊
    @Override
    public Object poll() {
        if(front!=null){
            Node p = front;
            front = front.next;//隊首節點出列
            if(p==rear) //被刪除的節點是隊尾節點時候
                rear=null;
            return p.data;
        }else
            return null;
    }

}

其中,Node.java 節點類:

public class Node {
    public Object data;//存放節點值
    public 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;
    }
}

4.優先級隊列

4.1 節點中data類 PriorityQData.java

/*
* 優先級隊列
* 一種帶有優先級的隊列
* 約定關鍵字最小的數據元素具有最高優先級,並且排在隊首
* 優先級隊列中的數據元素插入也不僅僅限制在隊尾進行,而是順序插入到隊列的 合適位置,以確保隊列的優先級順序
*
*
* 此類爲優先級隊列的節點中data類的描述
* */
public class PriorityQData {
    public Object elem; //節點類的數據元素值
    public int priority;//節點類的優先數
    //構造函數
    public PriorityQData() {
        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;
    }
}

4.2 節點類 Node.java

public class Node {
    public Object data;//存放節點值
    public 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;
    }
}

4.3 優先級隊列 PriorityQueue.java

public class PriorityQueue implements IQueue {
    private Node front;//隊首的引用
    private Node rear;//隊尾的引用

    //構造函數
    public PriorityQueue() {
        front = rear = null;
    }

    //隊列置空
    @Override
    public void clear() {
        front = rear = null;
    }

    //隊列判空
    @Override
    public boolean isEmpty() {
        return front==null;
    }

    //求隊列長度
    @Override
    public int length() {
        Node p = front;
        int length = 0;
        while(p!=null){
            p = p.next;
            ++length;
        }
        return length;
    }

    //讀取隊首元素
    @Override
    public Object peek() {
        if(front == null)
            return null;
        else
            return front.data;
    }

    //入隊
    @Override
    public void offer(Object x) throws Exception {
        PriorityQData pn = (PriorityQData)x;
        Node s = new Node(pn);  //構造一個新節點
        if(front == null)   //隊列爲空
            front = rear = s;//修改隊列的首位節點
        else{
            Node p = front,q = front;
            //新結點的數據域值與隊列節點的數據域值相比較
            while(p!=null&&pn.priority>=((PriorityQData)p.data).priority){
                q = p;
                p = p.next;
            }
            if(p == null){  //p爲空,表示遍歷到了隊列尾部
                rear.next = s;//將新節點加入到隊尾
                rear = s;//修改隊尾指針
            }else if(p == front){//p的優先級大於隊首節點的優先級
                s.next = front;//將新結點加入到隊首
                front = s;//修改隊首節點
            }else{  //新結點加入隊列中部
                q.next = s;
                s.next = p;
            }
        }
    }

    //出隊
    @Override
    public Object poll() {
        if(front == null)
            return null;
        else{
            Node p = front;
            front = p.next;
            return p.data;
        }
    }

    //輸出
    public void display(){
        if(!isEmpty()){
            Node p = front;
            while(p!=rear.next){
                PriorityQData q = (PriorityQData)p.data;
                System.out.println(q.elem+" "+q.priority);
                p = p.next;
            }
        }else{
            System.out.println("此隊列爲空");
        }
    }

}

數據結構這個系列是我學習時做的筆記,會持續更新,詳見我的github(地址在文章開頭)或我的其他博文,感覺不錯的話,關注一下吧!

發佈了27 篇原創文章 · 獲贊 49 · 訪問量 2263
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章