結構與演算法(02):佇列和棧結構

知了一笑發表於2020-09-09

本文原始碼:GitHub·點這裡 || GitEE·點這裡

一、佇列結構

1、基礎概念

佇列是一種特殊的線性表,特殊之處在於它只允許在表的前端(front)進行刪除操作,而在表的後端(rear)進行插入操作,和棧一樣,佇列是一種操作受限制的線性表。進行插入操作的端稱為隊尾,進行刪除操作的端稱為隊頭。

2、特點描述

佇列是一個有序列表,可以用陣列或是連結串列來實現,遵循先進先出的原則。即:先進入佇列的資料,會先取出;後進入佇列的資料,要後取出;即FIFO原則。

入佇列示意圖

出佇列示意圖

通過上述兩張圖解,不難發現佇列結構的一些特點:

  • 先進入的資料先出去;
  • 資料從隊尾進入,從隊首出去;
  • 基於陣列描述佇列下標變更頻繁;
  • 出佇列演算法可以基於容器大小取模;

佇列結構的核心是對容器內是否空、是否滿標誌的判斷演算法,即容器為空不可再取,容器已滿無法再存;該演算法結構在倉儲領域的適應非常廣泛。

3、訊息佇列

訊息佇列就是基於資料結構中的“先進先出”策略實現的,將訊息以排隊的方式放入佇列中,然後出佇列被消費:

有時候某類訊息消費需要有順序控制,即可以對訊息中的公共ID做取模處理,即把某類訊息都置於一個佇列中即可。

4、API使用案例

LinkedList類實現Queue佇列介面,因此可以基於LinkedList模擬佇列效果。

import java.util.LinkedList;
import java.util.Queue;

public class M01_Queue {
    public static void main(String[] args) {
        // 入佇列
        Queue<String> queue = new LinkedList<>();
        queue.add("head") ;
        queue.add("middle") ;
        queue.add("tail") ;
        // 當佇列出資料之後,size是不斷變化的
        int queueSize = queue.size() ;
        int loop = 0 ;
        // 根據佇列大小,不斷出佇列
        while (loop < queueSize) {
            System.out.println(queue.poll());
            System.out.println(queue);
            loop ++ ;
        }
    }
}

二、棧結構

1、基礎概念

棧(stack)又名堆疊,它是一種運算受限的線性表。限定僅在表尾進行插入和刪除操作的線性表。這一端被稱為棧頂,相對地,把另一端稱為棧底。向一個棧插入新元素又稱作進棧、入棧或壓棧(push),它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個棧刪除元素又稱作出棧或退棧(pop),它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。

2、特點描述

棧是一個先入後出的有序列表,新增和刪除只能在棧頂端(Top)操作,另一端為固定的一端,稱為棧底(Bottom)。

入棧示意圖

出棧示意圖

通過上述兩張圖解,棧結構的一些特點如下:

  • 進棧出棧都要通過棧頂端操作;
  • 進出棧都不移動棧底指標;
  • 進出棧都要移動棧頂指標;

基於棧的定義可知,最先放入棧中元素在棧底,最後放入的元素在棧頂,從棧容器中而刪除元素剛好相反,最後放入的元素最先刪除,最先放入的元素最後刪除。

3、遞回應用

棧在Java程式設計中的常見應用,(1)子程式的呼叫:在跳往子程式前,會將下個指令的地址存到堆疊中,直到子程式執行完後再將地址取出,退回到原來的程式中;(2)處理遞迴呼叫:和子程式的呼叫類似,除了儲存下一個指令的地址外,也要將引數、區域變數等資料存入堆疊中。

4、API使用案例

Stack棧API是Vector的一個子類,它實現了一個標準的後進先出的棧,堆疊只定義了預設建構函式,用來建立一個空棧,堆疊除了包括由Vector定義的所有方法,也定義了自己的一些方法。

import java.util.Stack;

public class M02_Stack {
    public static void main(String[] args) {
        // 入堆疊
        Stack<String> stack = new Stack<>() ;
        stack.push("First") ;
        stack.push("Second") ;
        stack.push("Third") ;
        int stackSize = stack.size() ;
        int loop = 0 ;
        // 根據棧大小,不斷出棧
        while (loop < stackSize) {
            System.out.println(stack.pop());
            System.out.println(stack);
            loop ++ ;
        }
    }
}

三、原始碼地址

GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent

推薦閱讀:資料結構和演算法

序號 文章標題
01 演算法和結構(01):稀疏陣列和二維陣列轉換
02 演算法應用:RSA演算法,加密解密,簽名驗籤流程詳解
03 演算法應用:遞迴演算法,處理樹形結構下的業務資料

相關文章