1. 程式人生 > 其它 >資料結構與算法系列(2)資料結構之佇列詳解

資料結構與算法系列(2)資料結構之佇列詳解

技術標籤:資料結構與演算法佇列資料結構環形佇列演算法

資料結構之佇列詳解

1、概述

佇列(Queue)是一種常用的資料結構,佇列(Queue)是一個有序列表,可以用陣列或是連結串列來實現。佇列(Queue)遵循先入先出的原則。即:先存入佇列的資料,要先取出,後存入的要後取出。佇列只允許在後端(tail)進行插入操作,在前端(head)進行出佇列(刪除)操作。

2、使用陣列實現佇列思路

佇列是有序列表,若使用陣列的結構來儲存佇列的資料,則佇列陣列的宣告,如下圖:

在這裡插入圖片描述

headtail分別記錄佇列前後端的下標,head

會隨著資料輸出而改變,而 rear 則是隨著資料輸入而改變。

藉助以下動態圖,能更好的理解,佇列的新增和刪除。
在這裡插入圖片描述

3、簡單佇列程式碼實現

基於java實現簡單佇列。

public class ArrayQueue {
    /**
     * 佇列頭部
     */
    private int head;
    /**
     *佇列尾部
     */
    private int tail;

    /**
     * 存放資料
     */
    private int[] array;

    /**
     *
     */
    private int capacity;
/** * 初始化陣列 * @param capacity */ public ArrayQueue(int capacity) { this.capacity = capacity; //初始化陣列 this.array=new int[capacity]; } /** * 入隊 */ public void add(int n){ if (isFull()){ throw new RuntimeException("佇列已經滿了"
); } array[tail]=n; //隊尾後移 tail++; } /** * 出佇列 * @return */ public int pop(){ if (isEmpty()){ throw new RuntimeException("佇列為空"); } int value=array[head]; //頭部指標後移 head++; return value; } /** * 獲取佇列頭資料 * @return */ public int getFirst(){ if (isEmpty()){ throw new RuntimeException("佇列為空"); } return array[head]; } /** * 獲取佇列頭資料 * @return */ public int getLast(){ if (isEmpty()){ throw new RuntimeException("佇列為空"); } return array[tail]; } /** * 佇列是否為空 * @return */ public boolean isEmpty(){ return head==tail; } /** * 佇列是否滿了 * @return */ public boolean isFull(){ return tail==capacity; } }

測試程式碼

public static void main(String[] args) {
        ArrayQueue arrayQueue=new ArrayQueue(5);
        arrayQueue.add(1);
        arrayQueue.add(2);
        arrayQueue.add(3);
        arrayQueue.add(4);
        arrayQueue.add(5);

        System.out.println(arrayQueue.pop());

        System.out.println(arrayQueue.getFirst());
        arrayQueue.add(6);
    }

上面實現的簡單佇列,有如下問題:佇列只能使用一次就不能用,即:當佇列新增資料加滿後,即使有資料出隊列了,也不能再新增新的資料。下面介紹的環形佇列,可以解決此問題。

4、環形佇列

public class CirleArrayQueue {

    /**
     * 測試
     * @param args
     */
    public static void main(String[] args) {
         CirleArrayQueue cirleArrayQueue=new CirleArrayQueue(6);
         cirleArrayQueue.add(1);
        cirleArrayQueue.add(2);
        cirleArrayQueue.add(3);
        cirleArrayQueue.add(4);
        cirleArrayQueue.add(5);
        System.out.println("原始佇列中的資料~~~~");
        cirleArrayQueue.list();
        System.out.println("出佇列的資料:"+ cirleArrayQueue.pop());
        cirleArrayQueue.list();
        System.out.println("新增資料後,佇列中的資料~~~~~");
        cirleArrayQueue.add(6);
        cirleArrayQueue.list();

    }
    /**
     * 佇列頭部
     */
    private int head;
    /**
     *佇列尾部
     */
    private int tail;

    /**
     * 存放資料
     */
    private int[] array;

    /**
     *
     */
    private int capacity;


    /**
     * 初始化陣列
     * @param capacity
     */
    public CirleArrayQueue(int capacity) {
        this.capacity = capacity;
        //初始化陣列
        this.array=new int[capacity];
    }

    /**
     * 入隊
     */
    public void add(int n){
        if (isFull()){
            throw new RuntimeException("佇列已經滿了");
        }
        array[tail]=n;
        //因為是環形佇列,使用取模
        tail=(tail+1)%capacity;
    }

    /**
     * 出佇列
     * @return
     */
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("佇列為空");
        }
        int value=array[head];
        //頭部指標後移
        head=(head+1)%capacity;
        return value;
    }

    /**
     * 獲取佇列頭資料
     * @return
     */
    public int getFirst(){
        if (isEmpty()){
            throw new RuntimeException("佇列為空");
        }
        return array[head];
    }

    /**
     * 獲取佇列頭資料
     * @return
     */
    public int getLast(){
        if (isEmpty()){
            throw new RuntimeException("佇列為空");
        }
        return array[tail];
    }

    /**
     * 佇列是否為空
     * @return
     */
    public boolean isEmpty(){
        return head==tail;
    }

    /**
     * 佇列是否滿了
     * @return
     */
    public boolean isFull(){
        return (tail+1)%capacity==head;
    }

    public int size(){
        return (tail+capacity-head)%capacity;
    }

    public void list(){
        for (int i = head; i <head+size() ; i++) {
            if (array[i]!=0)
              System.out.println(array[i]);
        }
    }
}