日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Java代碼手撕【數據結構】| 隊列的實現與優化指南

來源: 責編: 時間:2023-10-18 17:58:16 281觀看
導讀一、前言隊列是一種重要的數據結構,它按照“先入先出”(FIFO)的原則管理數據。本文將介紹隊列的概念、應用場景,以及如何使用數組實現普通隊列和環形隊列。二、內容2.1 概述2.1.1什么是隊列?隊列(Queue)是一種常見的數據結構

一、前言

隊列是一種重要的數據結構,它按照“先入先出”(FIFO)的原則管理數據。本文將介紹隊列的概念、應用場景,以及如何使用數組實現普通隊列和環形隊列。9RB28資訊網——每日最新資訊28at.com

二、內容

2.1 概述

2.1.1什么是隊列?

隊列(Queue)是一種常見的數據結構,它是一個線性數據結構,按照先入先出(FIFO,First-In-First-Out)的原則來管理數據。9RB28資訊網——每日最新資訊28at.com

注意,先入先出的原則就意味著最早進入隊列的元素將最先被取出,而最后進入隊列的元素將最后被取出,類似于排隊等候服務的行為。9RB28資訊網——每日最新資訊28at.com

隊列可以使用數組或鏈表來實現,具體實現方式因應用需求而異。9RB28資訊網——每日最新資訊28at.com

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

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

(2)應用場景

隊列的應用場景有很多,比如:9RB28資訊網——每日最新資訊28at.com

  1. 任務調度:操作系統使用隊列來管理待執行的任務或進程,確保按照進入隊列的順序分配處理時間。
  2. 數據緩沖:隊列用于數據傳輸和處理中,特別是在異步通信或生產者-消費者模式中,可以緩沖待處理的數據。
  3. 廣度優先搜索:在圖論和搜索算法中,隊列用于實現廣度優先搜索,以逐層遍歷圖結構。
  4. 打印任務隊列:打印機隊列用于管理待打印的文檔,確保按照順序打印。
  5. 網頁請求隊列:Web服務器可以使用隊列來處理收到的請求,以便有序響應客戶端請求。
  6. 排隊系統:在銀行、餐館、醫院等場所,隊列被用來管理等待服務的客戶,確保服務按照先來先服務的原則。
  7. ......

隊列在計算機科學和實際應用中非常有用,因為它們提供了一種有效的方法來管理和調度數據或任務,以確保按照特定的順序進行處理。9RB28資訊網——每日最新資訊28at.com

2.2 數組模擬隊列

下面,我們用數組來模擬一個簡單的隊列數據結構。9RB28資訊網——每日最新資訊28at.com

2.2.1 隊列類定義

首先給出類的定義:9RB28資訊網——每日最新資訊28at.com

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

在這里,ArrayQueue 是一個隊列類,使用數組作為內部數據存儲。它包括最大容量(maxSize)、隊列頭(front)、隊列尾(rear)和一個整數數組(data)來存放隊列的數據。9RB28資訊網——每日最新資訊28at.com

構造函數 ArrayQueue 接受一個整數參數 queueMaxSize,表示隊列的最大容量。初始化時,隊列的頭(front)和尾都(rear)被置為-1,表示隊列為空。9RB28資訊網——每日最新資訊28at.com

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

因此,初始隊列的結構圖如下:9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊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

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

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

再次強調一下,這里的 rear 變量用于指向隊列的最后一個數據,即隊列的尾部。9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊28at.com

2.2.5 deQueue

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

deQueue 方法用于取出隊列頭部的數據。首先,它會檢查隊列是否為空,如果是,將拋出一個運行時異常。如果隊列不為空,將 front 后移,然后返回隊頭的數據。9RB28資訊網——每日最新資訊28at.com

再次強調一下,這里的 front 變量指向的是隊列頭數據的前一個位置。9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊28at.com

2.2.6 headQueue

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

headQueue 方法用于獲取隊列頭部的數據,但不會將其出隊。它會檢查隊列是否為空,如果是,將拋出一個運行時異常。如果隊列不為空,將返回隊頭的數據。9RB28資訊網——每日最新資訊28at.com

2.2.7 showQueue

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

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

2.3 數組模擬環形隊列

(1)存在的問題

我們再來思考一個問題,雖然上述的隊列類實現了一個簡單的隊列數據結構,但仍然存在弊端。那就是數組使用一次后不能復用。9RB28資訊網——每日最新資訊28at.com

什么意思?9RB28資訊網——每日最新資訊28at.com

具體的,我們可以發現,每當隊列入隊一個數據,rear 變量就會往后移一位。每當有元素出隊,front 變量也會往后移一位。但是!一旦 rear 變量到達隊列的尾部,如果隊列頭部仍有空余的空間,就像這樣:9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊28at.com

那么此時根據 isFull() 方法的判斷下,該隊列是滿的。因此無法再入隊。9RB28資訊網——每日最新資訊28at.com

因此我們說,對于之前的隊列簡單實現來說,一旦隊列中的數據元素被取出,對應的數組位置就不能再次使用。數據從頭部添加,從尾部取出。一旦數組被填滿,我們無法再添加新的數據,即使隊列的前面已經有一些位置被釋放出來。這就會導致內存資源浪費。9RB28資訊網——每日最新資訊28at.com

為了解決這個問題,我們考慮使用環形隊列來優化。9RB28資訊網——每日最新資訊28at.com

那什么是環形隊列?9RB28資訊網——每日最新資訊28at.com

事實上,環形隊列是一種更高效的隊列實現方式,它允許隊列在達到最大容量后繼續添加元素,以覆蓋掉隊列頭部已經被取出的數據,實現數據的循環復用。9RB28資訊網——每日最新資訊28at.com

我們通過取模運算 % 來實現環形隊列。9RB28資訊網——每日最新資訊28at.com

(2)思路分析

當我們考慮了隊列內部數據存儲資源的復用后,我們就需要對 front 和 rear 變量的含義進行一個的調整(當然不調整也行,看個人習慣)。9RB28資訊網——每日最新資訊28at.com

具體如下:9RB28資訊網——每日最新資訊28at.com

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

當我們這樣約定好了后,就可以開始著手編寫代碼,得到一個環形隊列。9RB28資訊網——每日最新資訊28at.com

此時判斷隊列已滿或空時,邏輯需要略微調整。9RB28資訊網——每日最新資訊28at.com

判斷環形隊列空時,條件為:(rear == front)。因為當 rear 指針等于 front 指針時,表示隊列沒有有效的元素,即隊列為空。9RB28資訊網——每日最新資訊28at.com

判斷環形隊列滿時,條件為:(rear + 1) % maxSize == front9RB28資訊網——每日最新資訊28at.com

這該怎么理解?9RB28資訊網——每日最新資訊28at.com

事實上,在含義調整后,環形隊列中的 rear 變量指向的位置實際上就是預留給下次入隊的數據存放的位置。9RB28資訊網——每日最新資訊28at.com

當有一個新的數據入隊時,rear 指向的位置就可以存儲本次入隊的數據的值,然后,rear 就會加一并取余 maxSize ,用于尋找下一個可以存儲入隊數據的位置。9RB28資訊網——每日最新資訊28at.com

因此,當(rear + 1) % maxSize 的值剛好等于 front,那么證明該環形隊列已經滿了,沒有地方可以存儲下一次入隊的值。9RB28資訊網——每日最新資訊28at.com

舉一個例子,假設 maxSize 為 3,初始時 front 和 rear 都是0:9RB28資訊網——每日最新資訊28at.com

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

示意圖如下:9RB28資訊網——每日最新資訊28at.com

9RB28資訊網——每日最新資訊28at.com

3)優化后的隊列類

優化后的代碼實現如下:9RB28資訊網——每日最新資訊28at.com

class CircleArrayQueue {    private int maxSize;    private int front;    // 初始值為 0,指向隊頭數據,即首元素    private int rear;     // 初始值為 0,指向隊尾數據的下一個位置    private int[] data;	    ArrayQueue(int queueMaxSize) {        maxSize = queueMaxSize;	        data = new int[maxSize];    }	    // 判斷隊列是否為空    public boolean isEmpty() {        return rear == front;    }	    // 判斷隊列是否滿    public boolean isFull() {        return (rear + 1) % maxSize == front;    }	    // 入隊:添加數據到隊尾    public void enQueue(int num) {        if(isFull()) {            System.out.println("隊列已滿,無法入隊");            return;        }        data[rear] = num;        rear = (rear + 1) % maxSize;    }	    // 出隊,取出隊頭數據    public int deQueue() {        if(isEmpty()) {            throw new RuntimeException("隊列為空,無法出隊");         }        int value = data[front];        front = (front + 1) % maxSize;        return value;    }	    // 顯示隊列的頭數據(不是取出數據)    public int headQueue() {        if(isEmpty()) {            throw new RuntimeException("隊列為空,沒有數據");        }        return data[front];    }	    // 返回環形隊列當前的元素個數    public int size() {        return (rear + maxSize - front) % maxSize;    }	    // 打印隊列    public void showQueue() {        if(isEmpty()) {            System.out.println("隊列為空,沒有數據");            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]);        }    }}

三、總結

本文詳細介紹了隊列數據結構的概念和應用,包括普通隊列和環形隊列的實現。隊列是一種有序的數據結構,它在計算機科學中被廣泛應用,用于管理數據和任務的順序執行。普通隊列使用數組實現,但存在內存資源浪費的問題。為了解決這個問題,我們引入了環形隊列的概念,它允許隊列數據的循環復用,更加高效地利用內存。9RB28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-14006-0.htmlJava代碼手撕【數據結構】| 隊列的實現與優化指南

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

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

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

標簽:
  • 熱門焦點
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 六大權益!華為8月服務日開啟:手機免費貼膜、維修免人工費

    8月5日消息,一年一度的華為開發者大會2023(Together)日前在松山湖拉開帷幕,與此同時,華為8月服務日也式開啟,到店可享六大專屬權益。華為用戶可在華為商城Ap
  • K8S | Service服務發現

    一、背景在微服務架構中,這里以開發環境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環境或者
  • 如何通過Python線程池實現異步編程?

    線程池的概念和基本原理線程池是一種并發處理機制,它可以在程序啟動時創建一組線程,并將它們置于等待任務的狀態。當任務到達時,線程池中的某個線程會被喚醒并執行任務,執行完任
  • 19個 JavaScript 單行代碼技巧,讓你看起來像個專業人士

    今天這篇文章跟大家分享18個JS單行代碼,你只需花幾分鐘時間,即可幫助您了解一些您可能不知道的 JS 知識,如果您已經知道了,就當作復習一下,古人云,溫故而知新嘛。現在,我們就開始今
  • 虛擬鍵盤 API 的妙用

    你是否在遇到過這樣的問題:移動設備上有一個固定元素,當激活虛擬鍵盤時,該元素被隱藏在了鍵盤下方?多年來,這一直是 Web 上的默認行為,在本文中,我們將探討這個問題、為什么會發生
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 華為Mate 60保護殼曝光:碩大后置相機模組 凸起程度有驚喜

    這段時間以來,關于華為新旗艦的爆料日漸密集。據此前多方爆料,今年華為將開始恢復一年雙旗艦戰略,除上半年推出的P60系列外,往年下半年的Mate系列也將
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 尤溪县| 搜索| 松潘县| 平凉市| 台江县| 威宁| 固始县| 乐都县| 桃园县| 报价| 营山县| 沙坪坝区| 禹州市| 包头市| 贵阳市| 上杭县| 景东| 西盟| 石景山区| 高唐县| 阿瓦提县| 南澳县| 麻江县| 姚安县| 根河市| 清原| 喀什市| 万荣县| 宁化县| 陵川县| 游戏| 固安县| 时尚| 韶关市| 新河县| 乐平市| 墨竹工卡县| 仲巴县| 台前县| 民丰县| 阿拉善盟|