1. 程式人生 > 其它 >Linux 磁碟管理&&awk 命令

Linux 磁碟管理&&awk 命令

佇列簡介
佇列是一種特殊的線性表,只允許在表的前端(front)進行刪除操作,表後端(rear)進行插入操作。進行刪除操作的位置叫做對頭,進行插入操作的位置叫做隊尾。

特性
FIFO-First In First Out,先進先出儲存資料。

佇列實現主要分為順序佇列和迴圈佇列。

  • 順序佇列

建立順序佇列結構必須為其靜態或者動態分配一片的連續儲存空間,並且設定兩個指標進行管理,一個是對頭指標front,一個是隊尾指標rear。
初始化佇列時,rear=front=0,每次新增元素,rear增1;每次刪除元素,front增1。隨著新增和刪除操作的依次進行,佇列元素的個數不斷變化,佇列所佔用的儲存空間也在為佇列結構所分配的空間中移動。當rear增加到指向分配的連續空間之外時,佇列無法在插入元素,但這時往往還有大量的可用空間未被佔用,這些空間是已經出隊的佇列元素曾經佔用過的儲存單元。
順序佇列的溢位情況:
1)“下溢”現象:當佇列為空時,做出隊運算產生的溢位現象。“下溢”是正常現象,常用於程式控制轉義的條件。
2)“真上溢”現象:當佇列滿時,做入隊運算產生空間溢位的現象。“真上溢”是一種出錯狀態,應設法避免。
3)“假上溢”現象:由於入隊和出隊操作中,頭尾指標只增加不減少,導致被刪除元素所佔用過的空間無法被重新利用。當佇列中實際的元素個數小於儲存空間規模時,也可能由於尾指標已經到達儲存空間的上界點而不能做入隊操作。該現象稱之為“假上溢”現象。

圖示

順序佇列java程式碼陣列實現

點選檢視程式碼
/**
 * 資料實現順序佇列,包含isFull()、isEmpty()、insert()、remove()、peekFront()基本操作。
 * @date 2021/12/24
 */
@Data
@Slf4j
public class SequentialQueue {
    /** 佇列最大值 */
    private int maxSize;
    /** 陣列實現 */
    private Object[] queueArray;
    /** 隊頭 */
    private int front;
    /** 隊尾 */
    private int rear;

    public SequentialQueue(int maxSize) {
        this.maxSize = maxSize;
        this.queueArray = new Object[maxSize];
        this.front = 0;
        this.rear = 0;
    }

    /** 佇列是是否已滿 */
    public boolean isFull() {
        return rear == maxSize;
    }
    /** 佇列是否為空 */
    public boolean isEmpty() {
        return rear == 0;
    }
    /** 入隊 */
    public void insert(Object object) {
        // 隊尾是否是最大值
        boolean isFull = this.isFull();
        if (isFull) {
            log.error("佇列已滿,入隊失敗。");
        } else {
            queueArray[rear] = object;
            rear++;
        }
    }
    /** 出隊,刪除資料,對頭後移 */
    public void remove() {
        if (this.isEmpty()) {
            log.error("佇列已空,出隊失敗。");
        } else {
            queueArray[front] = null;
            front++;
        }

    }
    /** 出隊,刪除資料,對頭後移 */
    public Object peekFront() {
        return this.queueArray[front];
    }

    public static void main(String[] args) {
        SequentialQueue queue = new SequentialQueue(3);
        queue.insert(10);
        queue.insert(23);
        queue.insert(34);
        log.info("入隊後對頭值,num = {}", queue.peekFront());
        queue.remove();
        log.info("出隊後對頭值,num = {}", queue.peekFront());
    }
}
  • 迴圈佇列

在實際使用佇列時,為了能使佇列空間得到重複使用,往往會對佇列的使用方法稍加改進。無論插入或刪除操作,一旦rear指標或front指標增加1時超過了所分配的儲存空間,就讓它們指向儲存空間的起始位置。指標從maxSize-1增1變為0,可用取餘運算rear%maxSize和front%maxSize來實現。
實際上就是把佇列空間想象成環形空間,在空間中的儲存單元迴圈使用,用這種方法管理的佇列就是迴圈佇列。除了一些簡單應用之外,真正實用的佇列就是迴圈佇列。
圖示

迴圈佇列Java資料實現

點選檢視程式碼
/**
 * 陣列實現迴圈佇列,包含insert()、remove()、peekFront()、isFull()和isEmpty()方法。
 * @author Yoko
 */
@Data
@Slf4j
public class LoopQueue {
    /** 隊頭 */
    private int front;
    /** 隊尾 */
    private int rear;
    /** 實現陣列 */
    private Object[] queueArray;
    /** 陣列長度 */
    private int maxSize;
    /** 實際資料量 */
    private int nItem;

    public LoopQueue(int maxSize) {
        this.maxSize = maxSize;
        this.queueArray = new Object[maxSize];
        this.front = 0;
        this.rear = 0;
        this.nItem = 0;
    }

    /** 佇列是否為空 */
    public boolean isEmpty() {
        return this.nItem == 0;
    }
    /** 佇列是否已滿 */
    public boolean isFull() {
        return this.nItem == this.maxSize;
    }
    /** 入隊 */
    public void insert(Object object) {
        if (this.isFull()) {
            log.info("佇列已滿,入隊失敗。");
        } else {
            this.queueArray[rear] = object;
            this.rear = (this.rear + 1) % this.maxSize;
            this.nItem++;
        }
    }
    /** 出隊 */
    public void remove() {
        if (this.isEmpty()) {
            log.info("佇列已空,出隊失敗。");
        } else {
            this.queueArray[front] = null;
            this.front = (this.front + 1) % this.maxSize;
            this.nItem--;
        }
    }
    /** 檢視隊頭的值 */
    public Object peekFront() {
        if (!this.isEmpty()) {
            return this.queueArray[front];
        }
        return null;
    }

    public static void main(String[] args) {
        LoopQueue queue = new LoopQueue(4);
        queue.insert(155);
        queue.insert(10);
        queue.insert(2);
        log.info("入隊後資料:loopArray = {}", queue);
        log.info("對頭的值:front= {}", queue.peekFront());

        queue.remove();
        log.info("出隊後,queueArray = {}", queue);
        log.info("出隊後,對頭的值:front= {}", queue.peekFront());
        queue.insert(223);
        queue.insert(15);
        queue.insert(190);
        log.info("再次入隊後資料:loopArray = {}", queue);
    }
}
學習是一個循序漸進的過程,而學習的時間從來都不晚,只要你開始學習。