AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁 > 科技  > 軟件

Java代碼手撕【數(shù)據(jù)結(jié)構(gòu)】| 隊(duì)列的實(shí)現(xiàn)與優(yōu)化指南

來源: 責(zé)編: 時(shí)間:2023-10-18 17:58:16 255觀看
導(dǎo)讀一、前言隊(duì)列是一種重要的數(shù)據(jù)結(jié)構(gòu),它按照“先入先出”(FIFO)的原則管理數(shù)據(jù)。本文將介紹隊(duì)列的概念、應(yīng)用場景,以及如何使用數(shù)組實(shí)現(xiàn)普通隊(duì)列和環(huán)形隊(duì)列。二、內(nèi)容2.1 概述2.1.1什么是隊(duì)列?隊(duì)列(Queue)是一種常見的數(shù)據(jù)結(jié)構(gòu)

一、前言

隊(duì)列是一種重要的數(shù)據(jù)結(jié)構(gòu),它按照“先入先出”(FIFO)的原則管理數(shù)據(jù)。本文將介紹隊(duì)列的概念、應(yīng)用場景,以及如何使用數(shù)組實(shí)現(xiàn)普通隊(duì)列和環(huán)形隊(duì)列。QFJ28資訊網(wǎng)——每日最新資訊28at.com

二、內(nèi)容

2.1 概述

2.1.1什么是隊(duì)列?

隊(duì)列(Queue)是一種常見的數(shù)據(jù)結(jié)構(gòu),它是一個線性數(shù)據(jù)結(jié)構(gòu),按照先入先出(FIFO,F(xiàn)irst-In-First-Out)的原則來管理數(shù)據(jù)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

注意,先入先出的原則就意味著最早進(jìn)入隊(duì)列的元素將最先被取出,而最后進(jìn)入隊(duì)列的元素將最后被取出,類似于排隊(duì)等候服務(wù)的行為。QFJ28資訊網(wǎng)——每日最新資訊28at.com

隊(duì)列可以使用數(shù)組或鏈表來實(shí)現(xiàn),具體實(shí)現(xiàn)方式因應(yīng)用需求而異。QFJ28資訊網(wǎng)——每日最新資訊28at.com

隊(duì)列支持兩種主要的操作,即入隊(duì)(Enqueue)和出隊(duì)(Dequeue)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

  • 入隊(duì):將元素添加到隊(duì)列的尾部。
  • 出隊(duì):從隊(duì)列的頭部取出元素并刪除它。

(2)應(yīng)用場景

隊(duì)列的應(yīng)用場景有很多,比如:QFJ28資訊網(wǎng)——每日最新資訊28at.com

  1. 任務(wù)調(diào)度:操作系統(tǒng)使用隊(duì)列來管理待執(zhí)行的任務(wù)或進(jìn)程,確保按照進(jìn)入隊(duì)列的順序分配處理時(shí)間。
  2. 數(shù)據(jù)緩沖:隊(duì)列用于數(shù)據(jù)傳輸和處理中,特別是在異步通信或生產(chǎn)者-消費(fèi)者模式中,可以緩沖待處理的數(shù)據(jù)。
  3. 廣度優(yōu)先搜索:在圖論和搜索算法中,隊(duì)列用于實(shí)現(xiàn)廣度優(yōu)先搜索,以逐層遍歷圖結(jié)構(gòu)。
  4. 打印任務(wù)隊(duì)列:打印機(jī)隊(duì)列用于管理待打印的文檔,確保按照順序打印。
  5. 網(wǎng)頁請求隊(duì)列:Web服務(wù)器可以使用隊(duì)列來處理收到的請求,以便有序響應(yīng)客戶端請求。
  6. 排隊(duì)系統(tǒng):在銀行、餐館、醫(yī)院等場所,隊(duì)列被用來管理等待服務(wù)的客戶,確保服務(wù)按照先來先服務(wù)的原則。
  7. ......

隊(duì)列在計(jì)算機(jī)科學(xué)和實(shí)際應(yīng)用中非常有用,因?yàn)樗鼈兲峁┝艘环N有效的方法來管理和調(diào)度數(shù)據(jù)或任務(wù),以確保按照特定的順序進(jìn)行處理。QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2 數(shù)組模擬隊(duì)列

下面,我們用數(shù)組來模擬一個簡單的隊(duì)列數(shù)據(jù)結(jié)構(gòu)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2.1 隊(duì)列類定義

首先給出類的定義:QFJ28資訊網(wǎng)——每日最新資訊28at.com

class ArrayQueue {    private int maxSize;    private int front;    private int rear;    private int[] data;        ArrayQueue(int queueMaxSize) {        maxSize = queueMaxSize;    // 隊(duì)列的最大容量        data = new int[maxSize];    // 存放隊(duì)列的數(shù)據(jù)        front = -1;    // 指向隊(duì)列頭的前一個位置        rear = -1;     // 直接指向隊(duì)列尾部    }	    // ... 方法定義}

在這里,ArrayQueue 是一個隊(duì)列類,使用數(shù)組作為內(nèi)部數(shù)據(jù)存儲。它包括最大容量(maxSize)、隊(duì)列頭(front)、隊(duì)列尾(rear)和一個整數(shù)數(shù)組(data)來存放隊(duì)列的數(shù)據(jù)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

構(gòu)造函數(shù) ArrayQueue 接受一個整數(shù)參數(shù) queueMaxSize,表示隊(duì)列的最大容量。初始化時(shí),隊(duì)列的頭(front)和尾都(rear)被置為-1,表示隊(duì)列為空。QFJ28資訊網(wǎng)——每日最新資訊28at.com

需要注意這里的定義,在這里,front 變量指的是指向隊(duì)列首元素的前一個位置,而 rear 變量則指向隊(duì)列的尾部元素,即最后一個元素。QFJ28資訊網(wǎng)——每日最新資訊28at.com

因此,初始隊(duì)列的結(jié)構(gòu)圖如下:QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2.2 isEmpty

public boolean isEmpty() {    return rear == front;}

2.2.3 isFull

public boolean isFull() {    return rear == maxSize - 1;}

2.2.4 enQueue

// 入隊(duì)操作,添加數(shù)據(jù)到隊(duì)尾public void enQueue(int num) {    if(isFull()) {        System.out.println("隊(duì)列已滿,無法入隊(duì)");        return;    }    rear++;    data[rear] = num;}

enQueue 方法用于將數(shù)據(jù)添加到隊(duì)列的尾部。首先,它會檢查隊(duì)列是否已滿,如果是,將輸出一條錯誤消息并不執(zhí)行入隊(duì)操作。如果隊(duì)列未滿,將 rear 后移,然后將數(shù)據(jù)存入隊(duì)列尾部。QFJ28資訊網(wǎng)——每日最新資訊28at.com

再次強(qiáng)調(diào)一下,這里的 rear 變量用于指向隊(duì)列的最后一個數(shù)據(jù),即隊(duì)列的尾部。QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2.5 deQueue

// 出隊(duì)操作,取出隊(duì)頭數(shù)據(jù)public int deQueue() {    if(isEmpty()) {        throw new RuntimeException("隊(duì)列為空,無法出隊(duì)");     }    front++;    return data[front];}

deQueue 方法用于取出隊(duì)列頭部的數(shù)據(jù)。首先,它會檢查隊(duì)列是否為空,如果是,將拋出一個運(yùn)行時(shí)異常。如果隊(duì)列不為空,將 front 后移,然后返回隊(duì)頭的數(shù)據(jù)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

再次強(qiáng)調(diào)一下,這里的 front 變量指向的是隊(duì)列頭數(shù)據(jù)的前一個位置。QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2.6 headQueue

// 查看隊(duì)頭數(shù)據(jù)(注意不是取出數(shù)據(jù))public int headQueue() {    if(isEmpty()) {        throw new RuntimeException("隊(duì)列為空,沒有數(shù)據(jù)");    }    return data[front+1];}

headQueue 方法用于獲取隊(duì)列頭部的數(shù)據(jù),但不會將其出隊(duì)。它會檢查隊(duì)列是否為空,如果是,將拋出一個運(yùn)行時(shí)異常。如果隊(duì)列不為空,將返回隊(duì)頭的數(shù)據(jù)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.2.7 showQueue

// 打印隊(duì)列public void showQueue() {    if(isEmpty()) {        System.out.println("隊(duì)列為空,沒有數(shù)據(jù)");        return;    }    // 簡單的遍歷隊(duì)列    for(int i = 0; i < data.length; i++) {        System.out.printf("data[%d] = %d/n", i, data[i]);    }}

showQueue 方法用于簡單地打印隊(duì)列的所有元素。如果隊(duì)列為空,將輸出一條消息表示隊(duì)列為空。否則,它會簡單地遍歷隊(duì)列,打印每個數(shù)據(jù)元素的索引和值。QFJ28資訊網(wǎng)——每日最新資訊28at.com

2.3 數(shù)組模擬環(huán)形隊(duì)列

(1)存在的問題

我們再來思考一個問題,雖然上述的隊(duì)列類實(shí)現(xiàn)了一個簡單的隊(duì)列數(shù)據(jù)結(jié)構(gòu),但仍然存在弊端。那就是數(shù)組使用一次后不能復(fù)用。QFJ28資訊網(wǎng)——每日最新資訊28at.com

什么意思?QFJ28資訊網(wǎng)——每日最新資訊28at.com

具體的,我們可以發(fā)現(xiàn),每當(dāng)隊(duì)列入隊(duì)一個數(shù)據(jù),rear 變量就會往后移一位。每當(dāng)有元素出隊(duì),front 變量也會往后移一位。但是!一旦 rear 變量到達(dá)隊(duì)列的尾部,如果隊(duì)列頭部仍有空余的空間,就像這樣:QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

那么此時(shí)根據(jù) isFull() 方法的判斷下,該隊(duì)列是滿的。因此無法再入隊(duì)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

因此我們說,對于之前的隊(duì)列簡單實(shí)現(xiàn)來說,一旦隊(duì)列中的數(shù)據(jù)元素被取出,對應(yīng)的數(shù)組位置就不能再次使用。數(shù)據(jù)從頭部添加,從尾部取出。一旦數(shù)組被填滿,我們無法再添加新的數(shù)據(jù),即使隊(duì)列的前面已經(jīng)有一些位置被釋放出來。這就會導(dǎo)致內(nèi)存資源浪費(fèi)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

為了解決這個問題,我們考慮使用環(huán)形隊(duì)列來優(yōu)化。QFJ28資訊網(wǎng)——每日最新資訊28at.com

那什么是環(huán)形隊(duì)列?QFJ28資訊網(wǎng)——每日最新資訊28at.com

事實(shí)上,環(huán)形隊(duì)列是一種更高效的隊(duì)列實(shí)現(xiàn)方式,它允許隊(duì)列在達(dá)到最大容量后繼續(xù)添加元素,以覆蓋掉隊(duì)列頭部已經(jīng)被取出的數(shù)據(jù),實(shí)現(xiàn)數(shù)據(jù)的循環(huán)復(fù)用。QFJ28資訊網(wǎng)——每日最新資訊28at.com

我們通過取模運(yùn)算 % 來實(shí)現(xiàn)環(huán)形隊(duì)列。QFJ28資訊網(wǎng)——每日最新資訊28at.com

(2)思路分析

當(dāng)我們考慮了隊(duì)列內(nèi)部數(shù)據(jù)存儲資源的復(fù)用后,我們就需要對 front 和 rear 變量的含義進(jìn)行一個的調(diào)整(當(dāng)然不調(diào)整也行,看個人習(xí)慣)。QFJ28資訊網(wǎng)——每日最新資訊28at.com

具體如下:QFJ28資訊網(wǎng)——每日最新資訊28at.com

  • front 變量: 表示指向隊(duì)列的第一個元素,即首元素。 data[front] 是隊(duì)列的第一個元素。 front的初始值為 0。
  • rear 變量: 表示指向隊(duì)列最后一個元素的下一個位置。 這是為了表示隊(duì)列中哪些位置是可用的,以便繼續(xù)添加新的元素。 rear 的初始值同樣為 0。

當(dāng)我們這樣約定好了后,就可以開始著手編寫代碼,得到一個環(huán)形隊(duì)列。QFJ28資訊網(wǎng)——每日最新資訊28at.com

此時(shí)判斷隊(duì)列已滿或空時(shí),邏輯需要略微調(diào)整。QFJ28資訊網(wǎng)——每日最新資訊28at.com

判斷環(huán)形隊(duì)列空時(shí),條件為:(rear == front)。因?yàn)楫?dāng) rear 指針等于 front 指針時(shí),表示隊(duì)列沒有有效的元素,即隊(duì)列為空。QFJ28資訊網(wǎng)——每日最新資訊28at.com

判斷環(huán)形隊(duì)列滿時(shí),條件為:(rear + 1) % maxSize == frontQFJ28資訊網(wǎng)——每日最新資訊28at.com

這該怎么理解?QFJ28資訊網(wǎng)——每日最新資訊28at.com

事實(shí)上,在含義調(diào)整后,環(huán)形隊(duì)列中的 rear 變量指向的位置實(shí)際上就是預(yù)留給下次入隊(duì)的數(shù)據(jù)存放的位置。QFJ28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)有一個新的數(shù)據(jù)入隊(duì)時(shí),rear 指向的位置就可以存儲本次入隊(duì)的數(shù)據(jù)的值,然后,rear 就會加一并取余 maxSize ,用于尋找下一個可以存儲入隊(duì)數(shù)據(jù)的位置。QFJ28資訊網(wǎng)——每日最新資訊28at.com

因此,當(dāng)(rear + 1) % maxSize 的值剛好等于 front,那么證明該環(huán)形隊(duì)列已經(jīng)滿了,沒有地方可以存儲下一次入隊(duì)的值。QFJ28資訊網(wǎng)——每日最新資訊28at.com

舉一個例子,假設(shè) maxSize 為 3,初始時(shí) front 和 rear 都是0:QFJ28資訊網(wǎng)——每日最新資訊28at.com

  • 隊(duì)列為空:front = 0, rear = 0
  • 插入一個元素:front = 0, rear = 1
  • 插入第二個元素:front = 0, rear = 2
  • 插入第三個元素:front = 0, rear = 0(此時(shí)隊(duì)列滿,因?yàn)?(rear + 1) % maxSize 等于 front)
  • 取出第一個元素:front = 1, rear = 0(此時(shí)隊(duì)列有效元素個數(shù)為 2,因?yàn)?(0+3-1) % 3 == 2)

示意圖如下:QFJ28資訊網(wǎng)——每日最新資訊28at.com

QFJ28資訊網(wǎng)——每日最新資訊28at.com

3)優(yōu)化后的隊(duì)列類

優(yōu)化后的代碼實(shí)現(xiàn)如下:QFJ28資訊網(wǎng)——每日最新資訊28at.com

class CircleArrayQueue {    private int maxSize;    private int front;    // 初始值為 0,指向隊(duì)頭數(shù)據(jù),即首元素    private int rear;     // 初始值為 0,指向隊(duì)尾數(shù)據(jù)的下一個位置    private int[] data;	    ArrayQueue(int queueMaxSize) {        maxSize = queueMaxSize;	        data = new int[maxSize];    }	    // 判斷隊(duì)列是否為空    public boolean isEmpty() {        return rear == front;    }	    // 判斷隊(duì)列是否滿    public boolean isFull() {        return (rear + 1) % maxSize == front;    }	    // 入隊(duì):添加數(shù)據(jù)到隊(duì)尾    public void enQueue(int num) {        if(isFull()) {            System.out.println("隊(duì)列已滿,無法入隊(duì)");            return;        }        data[rear] = num;        rear = (rear + 1) % maxSize;    }	    // 出隊(duì),取出隊(duì)頭數(shù)據(jù)    public int deQueue() {        if(isEmpty()) {            throw new RuntimeException("隊(duì)列為空,無法出隊(duì)");         }        int value = data[front];        front = (front + 1) % maxSize;        return value;    }	    // 顯示隊(duì)列的頭數(shù)據(jù)(不是取出數(shù)據(jù))    public int headQueue() {        if(isEmpty()) {            throw new RuntimeException("隊(duì)列為空,沒有數(shù)據(jù)");        }        return data[front];    }	    // 返回環(huán)形隊(duì)列當(dāng)前的元素個數(shù)    public int size() {        return (rear + maxSize - front) % maxSize;    }	    // 打印隊(duì)列    public void showQueue() {        if(isEmpty()) {            System.out.println("隊(duì)列為空,沒有數(shù)據(jù)");            return;        }        // 遍歷思路,從 data[front] 遍歷到 data[front + size]        for(int i = front; i < front + size(); i++) {            System.out.printf("data[%d] = %d/n", i%maxSize, data[i%maxSize]);        }    }}

三、總結(jié)

本文詳細(xì)介紹了隊(duì)列數(shù)據(jù)結(jié)構(gòu)的概念和應(yīng)用,包括普通隊(duì)列和環(huán)形隊(duì)列的實(shí)現(xiàn)。隊(duì)列是一種有序的數(shù)據(jù)結(jié)構(gòu),它在計(jì)算機(jī)科學(xué)中被廣泛應(yīng)用,用于管理數(shù)據(jù)和任務(wù)的順序執(zhí)行。普通隊(duì)列使用數(shù)組實(shí)現(xiàn),但存在內(nèi)存資源浪費(fèi)的問題。為了解決這個問題,我們引入了環(huán)形隊(duì)列的概念,它允許隊(duì)列數(shù)據(jù)的循環(huán)復(fù)用,更加高效地利用內(nèi)存。QFJ28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-14006-0.htmlJava代碼手撕【數(shù)據(jù)結(jié)構(gòu)】| 隊(duì)列的實(shí)現(xiàn)與優(yōu)化指南

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 徹底搞懂hashMap底層原理

下一篇: 蘋果 Vision Pro 頭顯專利獲批:自動駕駛車內(nèi)提供沉浸式 VR 體驗(yàn)

標(biāo)簽:
  • 熱門焦點(diǎn)
Top