1、概述php
隊列是種線性集合,其元素從一端加入,從另外一端刪除;注:隊列是按照先進先出的方式處理的。從隊列中刪除元素的次序,與放置元素的次序是同樣的。html
(1)方法:前端
操做 | 描述 |
---|---|
enqueue | 向隊列末端添加一個元素 |
dequeue | 從隊列前段刪除一個元素 |
first | 考察隊列前端的那個元素 |
isempty | 斷定隊列是否爲空 |
size | 肯定隊列的元素數目 |
(2)過程java
(1)隊列是一種可存儲重複編碼密鑰的便利集合。git
(2)一般用表示排隊的隊列來實現模擬。web
2、用鏈表實現隊列編程
(1)那兩個分別指向鏈表首元素、鏈表末元素的引用方便隊列的鏈表實現。數組
(2)爲了從鏈表的末端出列,必須把一個臨時變量設置爲指向鏈表末端的元素。數據結構
(1)enqueue操做要求將新元素放到鏈表末端。架構
(2)注:新結點的next引用無需顯示的進行設置。
(1)enqueue和dequeue操做做用於隊列的對立端。
3、用數組實現隊列
(1)因爲隊列操做會修改集合的兩端,所以將一端固定於索引0處要求移動元素。
(2)非環形數組實現的元素移位,將產生O(n)的複雜度。
(3)把數組當作環形的,能夠出去在隊列的數組實現中把元素移位的須要。
(1)概述:簡單來說就是若是數組的最後一個索引後面跟的是第一個索引,就可用做環形數組。
(2)注:當添加和刪除元素時,不須要移動哪一個元素,可是必定要當心維護front和rear的值。
(1)首先,對於只有一端的隊列而言,符合的應當是先進先出的原則,因此最早進入的就應當是最早出去的元素,在進入多個元素之後,這一個先進入的元素就會變成一個隊列的隊尾,因此在書中有這樣一句話:
「爲了從鏈表的末端出列,必須把一個臨時變量設置爲指向鏈表末端的元素,而後把tail指針設置爲指向當前末端以前的結點。」
因此對於隊尾來說,有這樣一個rear的結點進行「管理」,防止元素丟失。
(2)而對於首來說,更是重要,它須要去肯定每個元素的位置,防止整個隊列元素的丟失。因此下圖的展現很可以體現隊列的這樣一種不一樣於鏈表的結構。
簡單表達就是頭結點其實至關於隊列第一個元素所在結點的前一個結點,經過其來肯定整個隊列內部元素的位置
(1)在咱們數組的實現方式中,用兩個int型變量用於記錄隊頭和隊尾的索引。
圖一:
(2)一個隊列的初始狀態,head和tail都指向初始位置(索引爲0處)。head永遠指向該隊列的隊頭元素,tail則指向該隊列最後一個元素的下一位置,當有入隊操做時:
圖2:
圖3:
(3)當有出隊操做時:
圖4:
(4)當遇到出隊操做時,head會移向下一元素位置。固然,對於這種方式入隊和出隊,隊空的判斷條件顯然是head=tail,隊滿的判斷條件是tail=array.length(數組最後一個位置的下一位置)。顯然,這種結構最致命的缺陷就是,tail只知道向後移動,一旦到達數組邊界就認爲隊滿,可是隊列可能時刻在出隊,也就是前面元素都出隊了,tail也不知道。例如:
圖5:
(5)此時tail判斷隊滿,咱們暫時認爲資源利用是能夠接受的,可是若是接下來不斷髮生出隊操做:
圖6:
(6)此時tail依然經過判斷,認爲隊滿,不能入隊,這時數組的利用率咱們是不能接受的,這樣浪費很大。因此,咱們引入循環隊列,tail能夠經過mode數組的長度實現迴歸初始位置,下面咱們具體來看一下。
按照咱們的想法,一旦tail到達數組邊界,那麼能夠經過與數組長度取模返回初始位置,這種狀況下判斷隊滿的條件爲tail=head
圖7:
(7)此時tail的值爲8,取模數組長度8獲得0,發現head=tail,此時認爲隊列滿員。這是合理的,可是咱們忽略了一個重要的點,判斷隊空的條件也是head=tail,那麼該怎麼區分是隊空仍是隊滿呢?解決辦法是,空出隊列中一個位置,若是(tail+1)%array.length=head,咱們就認爲隊滿,下面說明其合理性。
上面遇到的問題是,tail指向了隊尾的後一個位置,也就是新元素將要被插入的位置,若是該位置和head相等了,那麼必然說明當前狀態已經不能容納一個元素入隊(間接的說明隊滿)。由於這種狀況是和隊空的判斷條件是同樣的,因此咱們選擇捨棄一個節點位置,tail指向下一個元素的位置,咱們使用tail+1判斷下一個元素插入以後,是否還能再加入一個元素,若是不能了說明隊列滿,不能容納當前元素入隊(其實還剩下一個空位置),看圖:
圖8:
(8)tail經過取模,迴歸到初始位置,咱們判斷tail+1是否等於head,若是等於說明隊滿,不容許入隊操做,固然這是犧牲了一個節點位置來實現和判斷隊空的條件進行區分。上述文字基本完成了隊循環隊列的理論介紹,下面咱們看在Java中對該數據結構的具體實現是怎樣的。
問題1:最近在編寫代碼的過程當中,感受遇到的最多的就是空指針這個異常,以下圖,我在這裏分享一些我通常而言解決這一系列問題的一些技巧。
問題1解決方案:
(1)首先,在下面的地方能夠看見出錯的地方在哪裏,由於爲何會出現空指針呢,就是由於咱們想要索引的地方就是一個null,因此確定就會出現異常,所以呢,就通常而言我就再找一個新指針,做爲一個測試指針,找到出錯在哪一步。(這裏確定會有人說爲何不用bug,由於我以爲這個找錯也是一種方法,可是就我我的而言,我以爲bug一點一點的又點慢,因此就找了新方法)
(2)而後我通常而言會在循環裏找問題,由於有時候就是由於多移了一步可能就致使了這一個問題,因此咱們能夠給他減或加一次循環進行查看,結果是否能夠成功輸出。
因爲上週沒有進行測試,因此沒有錯題總結
代碼調試中的問題和解決過程, 一個問題加1分
我以爲這個中秋節過的很是充實,但願本身本身儘快再找到更好的狀態去面對新的學期,讓本身能夠學到更多知識,可讓本身在這學期能夠有更多的收穫。
代碼行數(新增/累積) | 博客量(新增/累積) | 學習時間(新增/累積) | |
---|---|---|---|
目標 | 5000行 | 30篇 | 400小時 |
第一週 | 0/0 | 1/1 | 6/6 |
第二週 | 1313/1313 | 1/2 | 20/26 |
第三週 | 901/2214 | 1/3 | 20/46 |
技能 | 課前評估 | 課後評估 |
---|---|---|
對編程總體的理解 | 2 | 6 |
架構設計、模塊化設計、接口設計 | 2 | 6 |
效能分析及改進 | 2 | 6 |
處理大數據 | 1 | 6 |
處理命令行參數和文件系統 | 1 | 6 |
自主學習的能力 | 5 | 7 |