Java隊(duì)列數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)
1.隊(duì)列的基本概念
什么是隊(duì)列?
- 隊(duì)列是一種特殊的線性表
- 它只允許在表的前端(隊(duì)頭)進(jìn)行刪除操作
- 在表的后端(隊(duì)尾)進(jìn)行插入操作
- 隊(duì)列是一個(gè)有序表(可以用數(shù)組或鏈表實(shí)現(xiàn))
- 隊(duì)列先進(jìn)先出
- 隊(duì)列開(kāi)辟的是一塊連續(xù)的空間
順序隊(duì)列中的溢出現(xiàn)象:
- 真溢出:當(dāng)隊(duì)列滿時(shí),做進(jìn)棧運(yùn)算產(chǎn)生空間溢出的現(xiàn)象。
- 假上溢:由于入隊(duì)和出隊(duì)操作中,頭尾指針只增加不減小,致使被刪元素的空間永遠(yuǎn)無(wú)法重新利用。當(dāng)隊(duì)列中實(shí)際的元素個(gè)數(shù)遠(yuǎn)遠(yuǎn)小于向量空間的規(guī)模時(shí),也可能由于尾指針已超越向量空間的上界而不能做入隊(duì)操作。
2.循環(huán)隊(duì)列
在實(shí)際使用隊(duì)列時(shí),為了使隊(duì)列空間能重復(fù)使用,往往對(duì)隊(duì)列的使用方法稍加改進(jìn):無(wú)論插入或刪除,一旦rear指針增1或front指針增1 時(shí)超出了所分配的隊(duì)列空間,就讓它指向這片連續(xù)空間的起始位置。自己真從MaxSize-1
增1變到0,可用取余運(yùn)算rear%MaxSize
和front%MaxSize
來(lái)實(shí)現(xiàn)。這實(shí)際上是把隊(duì)列空間想象成一個(gè)環(huán)形空間,環(huán)形空間中的存儲(chǔ)單元循環(huán)使用,用這種方法管理的隊(duì)列也就稱(chēng)為循環(huán)隊(duì)列。除了一些簡(jiǎn)單應(yīng)用之外,真正實(shí)用的隊(duì)列是循環(huán)隊(duì)列
3.實(shí)現(xiàn)思路
由于普通隊(duì)列存在溢出問(wèn)題所以這里用數(shù)組來(lái)實(shí)現(xiàn)環(huán)形隊(duì)列
- 1、front指向隊(duì)列的首元素 初始為0
- 2、rear指向隊(duì)列尾元素的后一個(gè)位置 (空出來(lái)的一塊空間作為約定)初始為0
- 3、隊(duì)列滿的條件
:(rear+1) % maxSize = front
- 4、隊(duì)列空的條件:
rear = front
- 5、隊(duì)列中元素的個(gè)數(shù)
:(rear+maxSize-front) % maxSize
為什么隊(duì)列滿的條件是(rear+1) % maxSize = front
(1)假設(shè)rear>front
rear-front=maxSize-1
rear+1-maxSize=front
由于當(dāng)rear>front
隊(duì)列滿時(shí)rear+1
一定等于maxSize
(rear+1) % maxSize = rear+1-maxSize =0
(2)假設(shè)front>rear
front-rear=1
rear+1=front
由于當(dāng)front>rear
時(shí)rear+1
一定小于maxSize
所以(rear+1) % maxSize=rear+1
(3)有上述所示可以得出隊(duì)列滿的條件是(rear+1) % maxSize = front
元素個(gè)數(shù)的計(jì)數(shù)與這相似
4.代碼實(shí)現(xiàn)
public class Queue { private int maxSzie; //隊(duì)列中能存儲(chǔ)的最大個(gè)數(shù) private int frontPoint; //頭指針指向隊(duì)頭 private int rearPoint; //尾指針指向隊(duì)尾的后一個(gè)數(shù)據(jù) private int[] array; //模擬隊(duì)列的數(shù)組 /** * 初始化隊(duì)列 */ public Queue(int max) { maxSzie = max; frontPoint = 0; rearPoint = 0; array = new int[max]; } /** * 判斷隊(duì)列是否為空 */ public boolean isEmpty(){ return frontPoint == rearPoint; } /** * 判斷隊(duì)列是否已滿 */ public boolean isFull(){ return (rearPoint+1)%maxSzie == frontPoint; } /** * 向隊(duì)列中添加數(shù)據(jù) */ public void add(int x){ if (isFull()){ System.out.println("當(dāng)前隊(duì)列已滿"); return; } //添加數(shù)據(jù) array[rearPoint] = x ; //后移尾指針 rearPoint = (rearPoint+1) % maxSzie; System.out.println("添加成功"); } /** * 取出隊(duì)列中的數(shù)據(jù) */ public int remove(){ if (isEmpty()){ throw new RuntimeException("當(dāng)前隊(duì)列為空"); } //把隊(duì)頭的值賦值給臨時(shí)變量 int x = array[frontPoint]; //移除數(shù)據(jù)后頭指針需要向后移動(dòng) 時(shí)其指向新的隊(duì)頭 frontPoint = (frontPoint+1) % maxSzie; System.out.println("移除成功"); return x; } /** * 獲取隊(duì)列頭數(shù)據(jù) */ public int gethead(){ if (isEmpty()){ throw new RuntimeException("當(dāng)前隊(duì)列為空"); } return array[frontPoint]; } /** * 遍歷隊(duì)列 */ public void show(){ int x = 0; for (int i = frontPoint; i <= (rearPoint+maxSzie-frontPoint)%maxSzie; i++) { x++; System.out.println("隊(duì)列的第"+x+"個(gè)數(shù)據(jù)是"+array[i]); } } }
public class QueueTest { public static void main(String[] args) { Queue queue = new Queue(5); Scanner scanner = new Scanner(System.in); char systemIn = ' '; boolean noEnd = true; while (noEnd){ System.out.println("a:add(添加數(shù)據(jù))"); System.out.println("r:remove(刪除數(shù)據(jù))"); System.out.println("h:head(獲取隊(duì)頭)"); System.out.println("s:show(遍歷隊(duì)列)"); System.out.println("e:exit(退出程序)"); System.out.println("請(qǐng)輸入字符"); systemIn = scanner.next().charAt(0); switch (systemIn){ case 'a': System.out.println("請(qǐng)輸入入隊(duì)的數(shù)據(jù)(數(shù)字)"); int x = Integer.parseInt(scanner.next()); queue.add(x); break; case 'r': queue.remove(); break; case 'h': int head = queue.gethead(); System.out.println("隊(duì)頭是"+head); break; case 's': queue.show(); break; case 'e': noEnd = false; break; } } } }
5.測(cè)試
到此這篇關(guān)于Java隊(duì)列數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java隊(duì)列數(shù)據(jù)結(jié)構(gòu)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Boot實(shí)戰(zhàn)之靜態(tài)資源處理
這篇文章主要介紹了Spring Boot實(shí)戰(zhàn)之靜態(tài)資源處理,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Java工作中常見(jiàn)的并發(fā)問(wèn)題處理方法總結(jié)
這篇文章主要介紹了Java工作中常見(jiàn)的并發(fā)問(wèn)題處理方法總結(jié),文章內(nèi)容講解的很清晰,有不太懂得同學(xué)可以跟著學(xué)習(xí)下2021-02-02Java并發(fā)編程之Semaphore(信號(hào)量)詳解及實(shí)例
這篇文章主要介紹了Java并發(fā)編程之Semaphore(信號(hào)量)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-06-06Spring Boot自定義配置實(shí)現(xiàn)IDE自動(dòng)提示功能
這篇文章主要介紹了Spring Boot自定義配置實(shí)現(xiàn)IDE自動(dòng)提示功能,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08java中對(duì)HashMap的put過(guò)程解讀
這篇文章主要介紹了java中對(duì)HashMap的put過(guò)程解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03Java中的動(dòng)態(tài)代理原理及實(shí)現(xiàn)
這篇文章主要介紹了Java中的動(dòng)態(tài)代理原理及實(shí)現(xiàn),動(dòng)態(tài)是相對(duì)于靜態(tài)而言,何為靜態(tài),即編碼時(shí)手動(dòng)編寫(xiě)代理類(lèi)、委托類(lèi),而動(dòng)態(tài)呢,是不編寫(xiě)具體實(shí)現(xiàn)類(lèi),等到使用時(shí),動(dòng)態(tài)創(chuàng)建一個(gè)來(lái)實(shí)現(xiàn)代理的目的,需要的朋友可以參考下2023-12-12Java 中一個(gè)類(lèi)提供一個(gè)默認(rèn)對(duì)象的多種方法
這篇文章主要介紹了Java 中一個(gè)類(lèi)提供一個(gè)默認(rèn)對(duì)象的多種方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Java實(shí)現(xiàn)Excel導(dǎo)入導(dǎo)出操作詳解
在平常的辦公工作中,導(dǎo)入導(dǎo)出excel數(shù)據(jù)是常見(jiàn)的需求,今天就來(lái)看一下通過(guò)Java如何來(lái)實(shí)現(xiàn)這個(gè)功能,感興趣的朋友可以了解下2022-02-02SpringBoot整合Spring?Security過(guò)濾器鏈加載執(zhí)行流程源碼分析(最新推薦)
Spring?Boot?對(duì)于?Spring?Security?提供了自動(dòng)化配置方案,可以使用更少的配置來(lái)使用?Spring?Security,這篇文章主要介紹了SpringBoot整合Spring?Security過(guò)濾器鏈加載執(zhí)行流程源碼分析,需要的朋友可以參考下2023-02-02