欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java  隊列實現(xiàn)原理及簡單實現(xiàn)代碼

 更新時間:2016年10月13日 16:05:44   作者:_Key  
這篇文章主要介紹了Java 隊列實現(xiàn)原理及簡單實現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下

Java 隊列實現(xiàn)原理

“隊列”這個單詞是英國人說的“排”。在英國“排隊”的意思就是站到一排當(dāng)中去。計算機(jī)科學(xué)中,隊列是一種數(shù)據(jù)結(jié)構(gòu),有點類似棧,只是在隊列中第一個插入的數(shù)據(jù)項也會最先被移除,而在棧中,最后插入的數(shù)據(jù)項最先移除。隊列的作用就像電影院前的人們站成的排一樣:第一個進(jìn)入附屬的人將最先到達(dá)隊頭買票。最后排隊的人最后才能買到票。

隊列和棧一樣也被用作程序員的工具。它也可以用于模擬真實世界的環(huán)境,例如模擬人們在銀行里排隊等待,飛機(jī)等待起飛,或者因特網(wǎng)絡(luò)上數(shù)據(jù)包等待傳送。

在計算機(jī)操作系統(tǒng)里,有各種隊列在安靜地工作著。打印作業(yè)在打印隊列中等待打印。當(dāng)在鍵盤上敲擊時,也有一個存儲鍵入內(nèi)容的隊列。同樣,如果使用文字處理程序敲擊一個鍵,而計算機(jī)又暫時要做其它的事,敲擊的內(nèi)容不會丟失,它會排在隊列中等待,直到文字處理程序有時間來讀取它。利用隊列保證了鍵入內(nèi)容在處理時其順序不會改變。

隊列的基本操作

隊列的兩個基本操作是inserting(插入)一個數(shù)據(jù)項,即把一個數(shù)據(jù)項放入隊尾,另一個是removing(移除)一個數(shù)據(jù)項,即移除隊頭的數(shù)據(jù)項。這類似于電影愛好者排隊買票時先排到隊尾,然后到達(dá)隊頭買票后離開隊列。

棧中的插入和移除數(shù)據(jù)項方法的命名是很標(biāo)準(zhǔn),稱為push和pop。隊列的方法至今沒有標(biāo)準(zhǔn)化的命名?!安迦搿笨梢苑Q為put、add或 enque,而“刪除”可以叫delete、get或deque。插入數(shù)據(jù)項的隊尾,也可以叫作back、tail或end。而移除數(shù)據(jù)項的隊頭,也可以叫head。下面將使用insert、remove、front和rear。

插入將值插入隊尾,同時隊尾箭頭增加一,指向新的數(shù)據(jù)項。

數(shù)據(jù)項被移除后,同時隊頭指針增加一。通常實現(xiàn)隊列時,刪除的數(shù)據(jù)項還會保存在內(nèi)存中,只是它不能被訪問了,因為隊頭指針已經(jīng)移到它的下一個位置了。

和棧中的情況不同,隊列中的數(shù)據(jù)項不總是從數(shù)組的0下標(biāo)處開始。移除了一些數(shù)據(jù)項后,隊頭指針會指向一個較高的下標(biāo)位置。

查看操作返回隊頭數(shù)據(jù)項的值,然而并不從隊中刪除這個數(shù)據(jù)項。

要是想從空隊列中移除一個數(shù)據(jù)項或想在已經(jīng)滿的隊列中插入一個數(shù)據(jù)項,應(yīng)用程序都要提示出錯消息。

循環(huán)隊列

當(dāng)在隊列中插入一個新數(shù)據(jù)項,隊頭的Rear箭頭向上移動,移向數(shù)組下標(biāo)大的位置。移除數(shù)據(jù)項時,隊尾Front指針也會向上移動。這種設(shè)計可能和人們直觀察覺相反,因為人們在買電影票排隊時,隊伍總是向前移動的,當(dāng)前面的人買完票離開隊伍后,其他人都向前移動。計算機(jī)中在隊列里刪除一個數(shù)據(jù)項后,也可以將其他數(shù)據(jù)項都向前移動,但這樣做的效率很差。相反,我們通過隊列中隊頭和隊尾指針的移動保持所有數(shù)據(jù)項的位置不變。

這樣設(shè)計的問題是隊尾指針很快就會移到數(shù)組的末端。雖然在數(shù)組的開始部分有空的數(shù)據(jù)項單元,這是移除的數(shù)據(jù)項的位置,但是由于因為隊尾指針不能再向后移動了,因此也不能再插入新的數(shù)據(jù)項,這該怎么辦?

環(huán)繞式處理

為了避免隊列不滿卻不能插入新數(shù)據(jù)項的問題,可以讓隊頭隊尾指針繞回到數(shù)組開始的位置。這就是循環(huán)隊列(有時也稱為“緩沖環(huán)”)。

指針回繞的過程:在隊列中插入足夠多的數(shù)據(jù)項,使隊尾指針指向數(shù)組的未端。再刪除幾個數(shù)組前端的數(shù)據(jù)項。現(xiàn)在插入一個新的數(shù)據(jù)項。就會看到隊尾指針從未端回繞到開始處的位置。新的數(shù)據(jù)項將插入這個位置。

插入更多的數(shù)據(jù)項。隊尾指針如預(yù)計的那樣向上移動。注意在隊尾指針回繞之后, 它現(xiàn)在處在隊頭指針的下面,這就顛倒了初始的位置。這可以稱為“折斷的序列”:隊列中的數(shù)據(jù)項存在數(shù)組兩個不同的序列中。

刪除足夠多的數(shù)據(jù)項后,隊頭指針也回繞。這時隊列的指針回到了初始運(yùn)行時的位置狀態(tài),隊頭指針在隊尾指針的下面。數(shù)據(jù)項也恢復(fù)為單一的連續(xù)的序列。

隊列的Java代碼

Queue.java程序創(chuàng)建了一個Queue類,它有insert()、remove()、peek()、isEmpty()和size()方法。

 package 棧和隊列;

class Queue{

 

    private int maxSize;

 

    private long[] queArray;

 

    private int front;

 

    private int rear;

 

    private int nItems;

 

 

    public Queue(int s){

 

       maxSize=s;

 

       queArray=new long[maxSize];

 

       front=0;

 

       rear=-1;

 

       nItems=0;

 

    }

 

 

    public void insert(long j){

 

       if(rear==maxSize-1)

 

           rear=-1;

 

       queArray[++rear]=j;

 

       nItems++;

 

    }

 

 

    public long remove(){

 

       long temp=queArray[front++];

 

       if(front==maxSize)

 

           front=0;

 

       nItems--;

 

       return temp;

 

    }

 

 

    public long peekFront(){

 

       return queArray[front];

 

    }

 

 

    public boolean isEmpty(){

 

       return (nItems==0);

 

    }

 

 

    public boolean ifFull(){

 

       return (nItems==maxSize);

 

    }

 

 

    public int size(){

 

       return nItems;

 

    }

 

 

}

 

程序?qū)崿F(xiàn)的Queue類中不但有front(隊頭)和rear(隊尾)字段,還有隊列中當(dāng)前數(shù)據(jù)項的個數(shù):nItems。

Insert()方法運(yùn)行的前提條件是隊列不滿。在Main()中沒有顯示這個方法,不過通常應(yīng)該先調(diào)用isFull()方法并且返回false 后,才調(diào)用insert()方法。(更通用的做法是在insert()方法中加入檢查隊列是否滿的判定,如果出現(xiàn)向已滿隊列里插入數(shù)據(jù)項的情況就拋出異常。) 

一般情況,插入操作是rear(隊尾指針)加一后,在隊尾指針?biāo)傅奈恢锰幉迦胄碌臄?shù)據(jù)。但是,當(dāng)rear指針指向數(shù)組的頂端,即 maxSize-1位置的時候,在插入數(shù)據(jù)項之前,它必須回繞到數(shù)組的底端?;乩@操作把rear設(shè)置為-1,因此當(dāng)rear加1后,它等于0,是數(shù)組底端的下標(biāo)值,最后nItem加一。

Remove()方法運(yùn)行的前提條件是隊列不空,在調(diào)用這個方法之前應(yīng)該調(diào)用isEmpty()方法確保隊列不空,或者在remove()方法里加入這種出錯檢查的機(jī)制。

移除(remove)操作總是由front指針得到隊頭數(shù)據(jù)項的值,然后將front加一。但是,如果這樣做使front的值超過數(shù)組的頂端,front就必須繞回到數(shù)組下標(biāo)為0的位置上。作這種檢驗的同時,先將返回值臨時存儲起來。最后nItem減一。

Peek()方法簡單易懂:它返回front指針?biāo)笖?shù)據(jù)項的值。有些隊列的實現(xiàn)也允許查看隊列隊尾數(shù)據(jù)項的值;比如這些方法可稱為peekFront()、peekRear()、或者只是front()和rear()。

isEmpty()、isFull()和size()方法的實現(xiàn)都依賴于nItems字段,它們分別返回nItems是否等于0,是否等于maxSize,或者返回它本身值。

在Queue類中包含數(shù)據(jù)項計數(shù)字段nItems會使insert()和remove()方法增加一點額外的操作,因為insert()和 remove()方法必須分別遞增和遞減這個變量值。這可能算不上額外的開銷,但是如果處理大量的插入和移除操作,這就可能會影響性能了。

因為,一些隊列的實現(xiàn)不使用數(shù)據(jù)項計數(shù)的字段,而是通過front和rear來計算出隊列是否空或者滿以及數(shù)據(jù)項的個數(shù)。如果這樣做,isEmpty()、ifFull()和size()例程會相當(dāng)復(fù)雜,因為就像前面講過的那樣,數(shù)據(jù)項的序列或者被折成兩段,或者是連續(xù)的一段。

而且,一個奇怪的問題出現(xiàn)了。當(dāng)隊列滿的時候,front和rear指針取一定的位置,但是當(dāng)隊列為空時,也可能呈現(xiàn)相同的位置關(guān)系。于是在同一時間,隊列似乎可能是滿的,也可能是空的。這個問題的解決方法是:讓數(shù)組容量比隊列數(shù)據(jù)項個數(shù)的最大值學(xué)要大一。

感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關(guān)文章

  • java HashMap 的工作原理詳解

    java HashMap 的工作原理詳解

    本文主要介紹java HashMap 的資料,這里整理了相關(guān)資料,并詳細(xì)說明了HashMap的用法,有需要的小伙伴可以參考下
    2016-09-09
  • Java Vector和ArrayList的異同分析及實例講解

    Java Vector和ArrayList的異同分析及實例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于Java Vector和ArrayList的異同分析及實例講解內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。
    2021-01-01
  • 詳解Java中的阻塞隊列

    詳解Java中的阻塞隊列

    在去年的面試過程中,被面試官問道“阻塞隊列”這個問題,因為當(dāng)時并沒有對此問題進(jìn)行深入理解,只是按照自己的理解說明了該問題,最后面試結(jié)果也不太好,今天對該問題進(jìn)行簡要的面試并記錄如下;如有錯誤,歡迎指正,需要的朋友可以參考下
    2021-06-06
  • Java經(jīng)典算法匯總之順序查找(Sequential Search)

    Java經(jīng)典算法匯總之順序查找(Sequential Search)

    Java查找算法之順序查找說明:順序查找適合于存儲結(jié)構(gòu)為順序存儲或鏈接存儲的線性表。 下面我們來詳細(xì)說明下
    2016-04-04
  • 詳解Java字符型常量和字符串常量的區(qū)別

    詳解Java字符型常量和字符串常量的區(qū)別

    Java 中的字符型常量和字符串常量是兩種不同的數(shù)據(jù)類型,本文將給大家詳細(xì)介紹一下Java字符型常量和字符串常量的區(qū)別,文中通過代碼講解的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • MyBatis主鍵自增的兩種實現(xiàn)方法

    MyBatis主鍵自增的兩種實現(xiàn)方法

    本文主要介紹了MyBatis主鍵自增的兩種實現(xiàn)方法,主要包括注解方式或配置文件方式來實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-01-01
  • SpringBoot整合redis中的JSON序列化文件夾操作小結(jié)

    SpringBoot整合redis中的JSON序列化文件夾操作小結(jié)

    在我們?nèi)粘5捻椖块_發(fā)中,使用redis作為緩存,來提高系統(tǒng)訪問速度和緩解系統(tǒng)壓力,在使用中遇到幾個問題,本文給大家詳細(xì)總結(jié)下,對SpringBoot整合redis?JSON序列化相關(guān)知識感興趣的朋友一起看看吧
    2022-02-02
  • RocketMQ的消費(fèi)者類型與最佳實踐詳解

    RocketMQ的消費(fèi)者類型與最佳實踐詳解

    這篇文章主要介紹了RocketMQ的消費(fèi)者類型與最佳實踐詳解,在?RocketMQ?5.0?中,更加強(qiáng)調(diào)了客戶端類型的概念,尤其是消費(fèi)者類型,為了滿足多樣的?RocketMQ?中一共有三種不同的消費(fèi)者類型,分別是?PushConsumer、SimpleConsumer?和?PullConsumer,需要的朋友可以參考下
    2023-10-10
  • Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重復(fù)讀取配置文件的方法

    Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重復(fù)讀取配置文

    這篇文章主要介紹了Java使用ByteArrayOutputStream 和 ByteArrayInputStream 避免重復(fù)讀取配置文件的方法,需要的朋友可以參考下
    2015-12-12
  • java正則表達(dá)式處理花括號內(nèi)容替換賦值問題

    java正則表達(dá)式處理花括號內(nèi)容替換賦值問題

    這篇文章主要介紹了java正則表達(dá)式處理花括號內(nèi)容替換賦值問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05

最新評論