国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列

這篇具有很好參考價(jià)值的文章主要介紹了算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


什么是隊(duì)列

??隊(duì)列跟棧一樣,也是一種操作受限的線性表數(shù)據(jù)結(jié)構(gòu)。不過,隊(duì)列是先進(jìn)者先出。

隊(duì)列和棧的區(qū)別

??棧只支持兩個(gè)基本操作:入棧 push()和出棧 pop()。隊(duì)列跟棧非常相似,支持的操作也很有限,最基本的操作也是兩個(gè):入隊(duì) enqueue(),放一個(gè)數(shù)據(jù)到隊(duì)列尾部;出隊(duì) dequeue(),從隊(duì)列頭部取一個(gè)元素。
算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列,算法與數(shù)據(jù)結(jié)構(gòu),算法,數(shù)據(jù)結(jié)構(gòu)
??隊(duì)列的概念很好理解,基本操作也很容易掌握。作為一種非常基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),隊(duì)列的應(yīng)用也非常廣泛,特別是一些具有某些額外特性的隊(duì)列,比如循環(huán)隊(duì)列、阻塞隊(duì)列、并發(fā)隊(duì)列。它們?cè)诤芏嗥讓酉到y(tǒng)、框架、中間件的開發(fā)中,起著關(guān)鍵性的作用。比如高性能隊(duì)列 Disruptor、Linux 環(huán)形緩存,都用到了循環(huán)并發(fā)隊(duì)列;Java concurrent 并發(fā)包利用 ArrayBlockingQueue 來實(shí)現(xiàn)公平鎖等。

隊(duì)列的類型

??跟棧一樣,隊(duì)列可以用數(shù)組來實(shí)現(xiàn),也可以用鏈表來實(shí)現(xiàn)。用數(shù)組實(shí)現(xiàn)的棧叫作順序棧,用鏈表實(shí)現(xiàn)的棧叫作鏈?zhǔn)綏?。同樣,用?shù)組實(shí)現(xiàn)的隊(duì)列叫作順序隊(duì)列,用鏈表實(shí)現(xiàn)的隊(duì)列叫作鏈?zhǔn)疥?duì)列。

順序隊(duì)列

public class ArrayQueue<T> {
    /**
     * 存儲(chǔ)數(shù)據(jù)的數(shù)組
     */
    private T[] tArr;
    /**
     * 頭坐標(biāo)
     */
    private int head = 0;
    /**
     * 尾坐標(biāo)
     */
    private int tail = -1;
    /**
     * 隊(duì)列容量
     */
    @Getter
    private int size = 0;

    /**
     * 構(gòu)造函數(shù)
     */
    public ArrayQueue(int arrLength) {
        tArr = (T[]) new Object[arrLength];
    }

    /**
     * 入隊(duì),線程不安全
     */
    public boolean offer(T t) {
        // 隊(duì)列是否已滿
        if (size == tArr.length) {
            return false;
        }

        // 尾是否已到數(shù)組最后,到達(dá)最后則移動(dòng)
        if (tail == tArr.length - 1) {
            // 移動(dòng)數(shù)組
            for (int i = 0; i < size; i++) {
                tArr[i] = tArr[head + i];
            }
            // 重設(shè)頭尾坐標(biāo)
            head = 0;
            tail = tail - size;
        }

        // 設(shè)置值
        tail++;
        tArr[tail] = t;
        size++;
        return true;
    }

    /**
     * 出隊(duì),線程不安全
     */
    public T take() {
        // 隊(duì)列是否為空
        if (size == 0) {
            return null;
        }

        // 取值
        T t = tArr[head];
        head++;
        size--;

        return t;
    }
}

??從代碼中我們看到,當(dāng)隊(duì)列的 tail 指針移動(dòng)到數(shù)組的最右邊后,如果有新的數(shù)據(jù)入隊(duì),我們可以將 head 到 tail 之間的數(shù)據(jù),整體搬移到數(shù)組中 0 到 size(隊(duì)列大?。?的位置。圖示如下:
算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列,算法與數(shù)據(jù)結(jié)構(gòu),算法,數(shù)據(jù)結(jié)構(gòu)

鏈?zhǔn)疥?duì)列

public class LinkedQueue<T> {
    /**
     * 隊(duì)列頭部節(jié)點(diǎn)
     */
    private QueueNode<T> headNode = null;
    /**
     * 隊(duì)列尾部節(jié)點(diǎn)
     */
    private QueueNode<T> tailNode = null;

    /**
     * 入隊(duì),線程不安全
     */
    public boolean offer(T t) {
        // 定義新節(jié)點(diǎn)
        QueueNode<T> newNode = new QueueNode<>();
        newNode.setData(t);

        // 對(duì)頭為空時(shí)設(shè)置為新節(jié)點(diǎn)
        if (headNode == null) {
            headNode = newNode;
        }

        // 隊(duì)尾非空時(shí),設(shè)置其下一節(jié)點(diǎn)為新節(jié)點(diǎn)
        if (tailNode != null) {
            tailNode.setNextNode(newNode);
        }

        // 重設(shè)隊(duì)尾節(jié)點(diǎn)
        tailNode = newNode;
        return true;
    }

    /**
     * 出隊(duì),線程不安全
     */
    public T take() {
        // 隊(duì)列為空
        if (headNode == null) {
            return null;
        }

        // 獲取當(dāng)前節(jié)點(diǎn)的數(shù)據(jù)
        T data = headNode.getData();

        // 取上一節(jié)點(diǎn)設(shè)置為棧頂
        headNode = headNode.getNextNode();
        return data;
    }


    @Data
    private class QueueNode<T> {
        /**
         * 數(shù)據(jù)
         */
        private T data;
        /**
         * 上一個(gè)節(jié)點(diǎn)
         */
        private QueueNode<T> nextNode = null;
    }
}

??基于鏈表的實(shí)現(xiàn),我們同樣需要兩個(gè)指針:head 指針和 tail 指針。它們分別指向鏈表的第一個(gè)結(jié)點(diǎn)和最后一個(gè)結(jié)點(diǎn)。如圖所示,入隊(duì)時(shí),tail->next= new_node, tail = tail->next;出隊(duì)時(shí),head = head->next。我們圖示如下:
算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列,算法與數(shù)據(jù)結(jié)構(gòu),算法,數(shù)據(jù)結(jié)構(gòu)

循環(huán)隊(duì)列

public class CircleQueue<T> {
    /**
     * 存儲(chǔ)數(shù)據(jù)的數(shù)組
     */
    private T[] tArr;
    /**
     * 頭坐標(biāo)
     */
    private int head = 0;
    /**
     * 尾坐標(biāo)
     */
    private int tail = -1;
    /**
     * 隊(duì)列容量
     */
    @Getter
    private int size = 0;

    /**
     * 構(gòu)造函數(shù)
     */
    public CircleQueue(int arrLength) {
        tArr = (T[]) new Object[arrLength];
    }

    /**
     * 入隊(duì),線程不安全
     */
    public boolean offer(T t) {
        // 隊(duì)列是否已滿
        if (size == tArr.length) {
            return false;
        }

        // 尾是否已到數(shù)組最后,到達(dá)最后則移動(dòng)
        int newTail = (tail + 1) % tArr.length;

        // 設(shè)置值
        tArr[newTail] = t;
        tail = newTail;
        size++;
        return true;
    }

    /**
     * 出隊(duì),線程不安全
     */
    public T take() {
        // 隊(duì)列是否為空
        if (size == 0) {
            return null;
        }

        // 取值
        T t = tArr[head];
        head = head + 1 % tArr.length;
        size--;

        return t;
    }
}

??循環(huán)隊(duì)列,顧名思義,它長(zhǎng)得像一個(gè)環(huán)。原本數(shù)組是有頭有尾的,是一條直線?,F(xiàn)在我們把首尾相連,扳成了一個(gè)環(huán)。我畫了一張圖,你可以直觀地感受一下。
算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列,算法與數(shù)據(jù)結(jié)構(gòu),算法,數(shù)據(jù)結(jié)構(gòu)

??我們可以發(fā)現(xiàn),圖中這個(gè)隊(duì)列的大小為 8,當(dāng)前 head=4,tail=6。當(dāng)有一個(gè)新的元素 a 入隊(duì)時(shí),我們放入下標(biāo)為 7 的位置,把 tail 更新為 7。當(dāng)再有一個(gè)元素 b 入隊(duì)時(shí),我們將 b 放入下標(biāo)為 0 的位置,然后 tail 更新為0。

??從上面的圖中我們可以看到,隊(duì)列為空的條件是head = tail ,而隊(duì)列滿的條件是(tail + 1) = head,當(dāng)tail + 1 > 8 時(shí),tail + 1 = 0。而這個(gè)操作可以用(tail + 1)對(duì) 8 取模來完成,即隊(duì)列滿的條件是 (tail + 1) % 8 = head。

阻塞隊(duì)列

??阻塞隊(duì)列其實(shí)就是在隊(duì)列基礎(chǔ)上增加了阻塞操作。簡(jiǎn)單來說,就是在隊(duì)列為空的時(shí)候,從隊(duì)頭取數(shù)據(jù)會(huì)被阻塞。因?yàn)榇藭r(shí)還沒有數(shù)據(jù)可取,直到隊(duì)列中有了數(shù)據(jù)才能返回;如果隊(duì)列已經(jīng)滿了,那么插入數(shù)據(jù)的操作就會(huì)被阻塞,直到隊(duì)列中有空閑位置后再插入數(shù)據(jù),然后再返回。
算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列,算法與數(shù)據(jù)結(jié)構(gòu),算法,數(shù)據(jù)結(jié)構(gòu)

并發(fā)隊(duì)列

??線程安全的隊(duì)列我們叫作并發(fā)隊(duì)列。最簡(jiǎn)單直接的實(shí)現(xiàn)方式是直接在 enqueue()、dequeue() 方法上加鎖,但是鎖粒度大并發(fā)度會(huì)比較低,同一時(shí)刻僅允許一個(gè)存或者取操作。實(shí)際上,基于數(shù)組的循環(huán)隊(duì)列,利用 CAS 原子操作,可以實(shí)現(xiàn)非常高效的并發(fā)隊(duì)列。這也是循環(huán)隊(duì)列比鏈?zhǔn)疥?duì)列應(yīng)用更加廣泛的原因。在實(shí)戰(zhàn)篇講 Disruptor 的時(shí)候,我會(huì)再詳細(xì)講并發(fā)隊(duì)列的應(yīng)用。

總結(jié)

??隊(duì)列最大的特點(diǎn)就是先進(jìn)先出,主要的兩個(gè)操作是入隊(duì)和出隊(duì)。跟棧一樣,它既可以用數(shù)組來實(shí)現(xiàn),也可以用鏈表來實(shí)現(xiàn)。用數(shù)組實(shí)現(xiàn)的叫順序隊(duì)列,用鏈表實(shí)現(xiàn)的叫鏈?zhǔn)疥?duì)列。特別是長(zhǎng)得像一個(gè)環(huán)的循環(huán)隊(duì)列。在數(shù)組實(shí)現(xiàn)隊(duì)列的時(shí)候,會(huì)有數(shù)據(jù)搬移操作,要想解決數(shù)據(jù)搬移的問題,我們就需要像環(huán)一樣的循環(huán)隊(duì)列。文章來源地址http://www.zghlxwxcb.cn/news/detail-531015.html

到了這里,關(guān)于算法與數(shù)據(jù)結(jié)構(gòu)-隊(duì)列的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 算法與數(shù)據(jù)結(jié)構(gòu)(四)--隊(duì)列

    算法與數(shù)據(jù)結(jié)構(gòu)(四)--隊(duì)列

    隊(duì)列是另一種特殊的表,這種表只在表首(也稱為隊(duì)首)進(jìn)行刪除操作,只在表尾進(jìn)行插入操作。 隊(duì)列的修改是按 先進(jìn)先出 的規(guī)則進(jìn)行的,所以隊(duì)列又稱為先進(jìn)先出表,F(xiàn)irst In First Out,簡(jiǎn)稱FIFO表。映射到生活中就是排隊(duì)的隊(duì)伍。 如示意圖所示,a(1)就是隊(duì)首元素,a(n)就是隊(duì)

    2024年02月15日
    瀏覽(29)
  • 數(shù)據(jù)結(jié)構(gòu)與算法04:隊(duì)列

    數(shù)據(jù)結(jié)構(gòu)與算法04:隊(duì)列

    目錄 什么是隊(duì)列? 循環(huán)隊(duì)列 雙端隊(duì)列 阻塞隊(duì)列 隊(duì)列的應(yīng)用場(chǎng)景 每日一練 在 上一篇文章 中講述了棧:先進(jìn)后出就是棧,隊(duì)列剛好相反, 先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu)就是隊(duì)列 ,還是拿紙箱子來舉例:隊(duì)列可以理解為一個(gè)沒有底的紙箱子,往箱子里面放書,一本一本疊上去,但是

    2024年02月06日
    瀏覽(26)
  • Python數(shù)據(jù)結(jié)構(gòu)與算法-數(shù)據(jù)結(jié)構(gòu)(列表、棧、隊(duì)列、鏈表)

    Python數(shù)據(jù)結(jié)構(gòu)與算法-數(shù)據(jù)結(jié)構(gòu)(列表、棧、隊(duì)列、鏈表)

    數(shù)據(jù)結(jié)構(gòu)是指相互之間存在這一種或者多種關(guān)系的數(shù)據(jù)元素的集合和該集合中元素之間的關(guān)系組成。 簡(jiǎn)單來說,數(shù)據(jù)結(jié)構(gòu)就是設(shè)計(jì)數(shù)據(jù)以何種方式組織并存儲(chǔ)在計(jì)算機(jī)中。 比如:列表、集合與字典等都是一種數(shù)據(jù)結(jié)構(gòu)。 N.Wirth:“程序=數(shù)據(jù)結(jié)構(gòu)+算法” 數(shù)據(jù)結(jié)構(gòu)按照其 邏輯結(jié)

    2024年02月08日
    瀏覽(35)
  • 數(shù)據(jù)結(jié)構(gòu)之棧、隊(duì)列——算法與數(shù)據(jù)結(jié)構(gòu)入門筆記(四)

    數(shù)據(jù)結(jié)構(gòu)之棧、隊(duì)列——算法與數(shù)據(jù)結(jié)構(gòu)入門筆記(四)

    本文是算法與數(shù)據(jù)結(jié)構(gòu)的學(xué)習(xí)筆記第四篇,將持續(xù)更新,歡迎小伙伴們閱讀學(xué)習(xí) 。有不懂的或錯(cuò)誤的地方,歡迎交流 棧是一種線性數(shù)據(jù)結(jié)構(gòu),其 只允許在固定的一端進(jìn)行插入和刪除 元素操作。進(jìn)行數(shù)據(jù)插入和刪除操作的一端稱為棧頂 (Top), 另一端稱為棧底 (Bottom)。棧中的

    2024年02月08日
    瀏覽(23)
  • 數(shù)據(jù)結(jié)構(gòu)與算法:棧和隊(duì)列

    數(shù)據(jù)結(jié)構(gòu)與算法:棧和隊(duì)列

    棧是一種后入先出(LIFO)的線性邏輯存儲(chǔ)結(jié)構(gòu)。只允許在棧頂進(jìn)行進(jìn)出操作。 基本操作包括:入棧(push)/出棧(pop)/獲取棧頂元素(peek)。 棧的實(shí)現(xiàn)主要有兩種: 1. 數(shù)組實(shí)現(xiàn),即順序棧 2. 鏈表實(shí)現(xiàn),即鏈?zhǔn)綏?無論是以數(shù)組還是以鏈表實(shí)現(xiàn),入棧、出棧的時(shí)間復(fù)雜度都是

    2024年02月11日
    瀏覽(22)
  • 數(shù)據(jù)結(jié)構(gòu)與算法-雙端隊(duì)列

    Gitee上開源的數(shù)據(jù)結(jié)構(gòu)與算法代碼庫(kù):數(shù)據(jù)結(jié)構(gòu)與算法Gitee代碼庫(kù) 雙端隊(duì)列、隊(duì)列、棧對(duì)比 定義 特點(diǎn) 隊(duì)列 一端刪除(頭)另一端添加(尾) First In First Out 棧 一端刪除和添加(頂) Last In First Out 雙端隊(duì)列 兩端都可以刪除、添加 優(yōu)先級(jí)隊(duì)列 優(yōu)先級(jí)高者先出隊(duì) 延時(shí)隊(duì)列 根據(jù)

    2024年02月13日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】設(shè)計(jì)循環(huán)隊(duì)列

    【數(shù)據(jù)結(jié)構(gòu)與算法】設(shè)計(jì)循環(huán)隊(duì)列

    ??????? 個(gè)人主頁(yè):簡(jiǎn) 料 ???? 所屬專欄:C++ ???? 個(gè)人社區(qū):越努力越幸運(yùn)社區(qū) ???? 簡(jiǎn)? ? ?? 介: 簡(jiǎn)料簡(jiǎn)料,簡(jiǎn)單有料~在校大學(xué)生一枚,專注C/C++/GO的干貨分享,立志成為您的好幫手 ~ C/C++學(xué)習(xí)路線 (點(diǎn)擊解鎖) ?? C語言階段(已結(jié)束) ?? 數(shù)據(jù)結(jié)構(gòu)與算法(ing) ?

    2024年01月17日
    瀏覽(21)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】隊(duì)列的實(shí)現(xiàn)

    【數(shù)據(jù)結(jié)構(gòu)與算法】隊(duì)列的實(shí)現(xiàn)

    ?? 作者:@ 阿亮joy. ?? 專欄:《數(shù)據(jù)結(jié)構(gòu)與算法要嘯著學(xué)》 ?? 座右銘:每個(gè)優(yōu)秀的人都有一段沉默的時(shí)光,那段時(shí)光是付出了很多努力卻得不到結(jié)果的日子,我們把它叫做扎根 隊(duì)列:只允許在一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作的特殊線性表,隊(duì)列具有先

    2024年02月07日
    瀏覽(52)
  • 【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊(duì)列(順序隊(duì)列--循環(huán)隊(duì)列--優(yōu)先級(jí)隊(duì)列--鏈隊(duì)列)

    【數(shù)據(jù)結(jié)構(gòu)與算法】03 隊(duì)列(順序隊(duì)列--循環(huán)隊(duì)列--優(yōu)先級(jí)隊(duì)列--鏈隊(duì)列)

    隊(duì)列( queue )是一種常見的數(shù)據(jù)結(jié)構(gòu),它遵循先進(jìn)先出(FIFO)的原則。隊(duì)列可以理解為一個(gè)具有兩個(gè)端點(diǎn)的線性數(shù)據(jù)結(jié)構(gòu),其中一個(gè)端點(diǎn)稱為\\\"隊(duì)尾\\\"(rear),用于插入新元素,另一個(gè)端點(diǎn)稱為\\\"隊(duì)首\\\"(front),用于移除元素。新元素被插入到隊(duì)尾,而最早插入的元素總是在隊(duì)

    2024年02月08日
    瀏覽(21)
  • 【Java數(shù)據(jù)結(jié)構(gòu) -- 隊(duì)列:隊(duì)列有關(guān)面試oj算法題】

    【Java數(shù)據(jù)結(jié)構(gòu) -- 隊(duì)列:隊(duì)列有關(guān)面試oj算法題】

    只允許在一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作得特殊線性表,隊(duì)列是 先進(jìn)先出 ,入隊(duì):進(jìn)行插入操作得一端稱為 隊(duì)尾(rear) ,出隊(duì):進(jìn)行刪除操作的一端稱為 隊(duì)頭(front) 。隊(duì)列Queue是個(gè)接口, 底層通過鏈表實(shí)現(xiàn)的 。 boolean offer(E e) – 入隊(duì)列 E poll() – 出隊(duì)

    2024年01月25日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包