隊列——數組結構實現(普通隊列)

一、隊列

1. 隊列的概念

  • 隊列的核心理念是:先進先出
  • 隊列是一種特殊的線性表:它只允許在表的前端(front)進行刪除操作,而在表的後端(tail)進行插入操作
  • 隊列和棧都是一種操作受限的線性表,其中進行插入操作的端稱之爲隊尾,進行刪除操作的端稱之爲隊首

2.隊列的屬性

  • getFront():獲取隊首的元素,但不進行出隊操作;
  • getSize():獲取隊列中元素的數量;
  • isEmpty():判斷隊列是否爲空;
  • enqueue():在隊尾tail插入元素;
  • dequeue():在隊首front刪除元素;

上述隊列的屬性抽象成接口,其代碼實現如下:

/**
 * @Author: zjtMeng
 * @Date: 2019/12/22 18:47
 * @Version 1.0
 */
public interface Queue<E> {

    void enqueue(E e);

    E dequeue();

    E getFront();

    int getSize();

    boolean isEmpty();
}

二、普通隊列ArrayQueue

  • 普通隊列概念是:底層通過數組來實現,且通過調用addLast()實現入隊操作,調用removeFirst()實現出隊操作;

  • 此部分會用到之前自己封裝的數組,其博客地址如下:自己封裝的數組Array

2.1基本方法的實現:

  • 隊列的有參構造方法和無參構造方法初始化隊列的容積,可以直接調用Array的構造方法
    public ArrayQueue(int capacity){
        array =new Array<>(capacity);
    }

    public ArrayQueue(){
        array = new Array<>();
    }
  • 入隊操作,通過調用Array中的addLast()方法。由於Array中在設計addLast()方法時,已經考慮了擴容的操作,因此實現隊列的入隊操作時,不必考慮擴容這部分情況;
    ArrayaddLast()方法和擴容操作代碼:
    /**
     * 調用add()方法,實現在所有元素之後添加一個新元素
     */
    public void addLast(E e){
        add(size,e);
    } 

    /**
     * 在index位置上插入元素e
     * @param index
     * @param e
     */
    public void add(int index,E e){
        //判斷傳入的插入位置參數是否規範以及合乎要求,
        if (index <0 || index> size)
            throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
        //判斷當前數組是否已經達到容量了
        if (size == data.length)
        	//調用resize()方法,進行擴容
            resize(2 * data.length);
        //從插入位置開始,後面的所有元素全部向後挪一位
        for (int i=size-1; i>=index; i--)
            data[i+1] = data[i];
        data[index] = e;
        size++;
    }

    /**
     * 擴容
     * @param newCapacity
     */
    private void resize(int newCapacity){
        E[] newData = (E[]) new Object[newCapacity];
        for (int i=0; i<size; i++){
            newData[i] = data[i];
        }
        data = newData;
    }

此處隊列調用Array中的addLast()方法,可以實現入隊操作;

  • 出隊操作,通過調用ArrayremoveFirst()方法。同樣的,由於Array中在設計removeFirst()方法時,已經考慮了縮容的操作,因此實現隊列的入隊操作時,不必考慮擴容這部分情況;
    ArrayremoveFirst()方法和縮容操作代碼:
    /**
     * 刪除數組最後一個元素,返回刪除的元素
     * @return
     */
    public E removeLast(){
        return remove(size-1);
    }
    
    /**
     * 從數組中刪除指定位置的元素,並返回刪除的元素
     * @param index
     * @return
     */
    public E remove(int index){
        //判斷傳入的插入位置參數是否規範以及合乎要求,
        if (index <0 || index> size)
            throw new IllegalArgumentException("add failed. Require index >=0 || index < size");
        E ret = data[index];
        for (int i = index; i < size ; i++) {
            data[i] = data[i+1];
        }
        size--;
        //此處將移除位置置爲null,是爲了 loitering object != memory leak
        data[size] = null;
        //當數組元素減少到一定程度(數組的容量的1/4。而不是1/2)時,數組容量縮小一倍,從而避免數組在1/2容積節點處位置來回擴容縮容操作
        if(size == data.length / 4 && data.length / 2 != 0)
            resize(data.length / 2);
        return ret;
    }

因此此處隊列調用Array中的removeFirst()方法,可以實現出隊操作;

2.2普通隊列的實現

代碼如下:

package dataStructure.chapter3;

import dataStructure.chapter1.Array;

/**
 * @Author: zjtMeng
 * @Date: 2019/12/22 18:50
 * @Version 1.0
 */
public class ArrayQueue<E> implements Queue<E> {

    private Array<E> array;

    //有參構造方法
    public ArrayQueue(int capacity){
        array =new Array<>(capacity);
    }

    public ArrayQueue(){
        array = new Array<>();
    }

    @Override
    public void enqueue(E e) {
        array.addLast(e);
    }

    @Override
    public E dequeue() {
        return array.removeFirst();
    }

    @Override
    public E getFront() {
        return array.getFirst();
    }

    @Override
    public int getSize() {
        return array.getSize();
    }

    @Override
    public boolean isEmpty() {
        return array.isEmpty();
    }

    public int getCapacity(){
        return array.getCapacity();
    }

    public String toString(){
        StringBuilder res = new StringBuilder();
        res.append("Queue");
        res.append("front[");
        for (int i = 0; i<array.getSize(); i++){
            res.append(array.get(i));
            if (i != array.getSize()-1)
                res.append(", ");
        }
        res.append("] tail");
        return res.toString();

    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章