每年的3月和4月都是跳槽季,各地考研成績陸續公佈,公務員考試也接近尾聲,無論是剛畢業的同學還是工作多年的老司機,新的一年裏都想再搏一搏,所以這兩個月被大家稱作“金三銀四”。
衆所周知,BAT 等互聯網名企,在招聘技術崗位的過程中,對算法和數據結構都會重點考察。所以,這段時間有意找工作的程序員們都在瘋狂刷算法題。
但算法易學難精,臨時抱佛腳大搞題海戰術其實很難順利進階,在刷題的同時,還需要梳理好知識結構,把算法從理論到實踐通通吃透之後才能拿到Dream Offer!
“一個優秀的程序員和一個不合格的程序員之間的區別在於,他是否將數據結構看得比代碼更重要。不合格的程序員總是在關注代碼,而優秀的程序員則會更看重數據結構。”
Pascal 之父及圖靈獎獲得者尼古拉斯·沃斯(Niklaus Wirth)也曾提出了一個著名的公式:算法+數據結構=程序。由此可見,數據結構和算法纔是程序的核心。
雖然數據結構和算法都無比重要,但現實情況卻是很多工作了三五年的程序員並不重視數據結構和算法,他們所實現的程序往往運行效率低且難以維護。
面試官爲什麼愛問數據結構與算法,答案很簡單:
算法能力能辨別一個程序員的技術功底是否紮實;
算法能力是發掘程序員的成長潛力的關鍵手段;
算法能力能夠協助判斷程序員在面對新問題時,分析並解決問題的能力。
接下來,異步君將帶大家瞭解算法與數據結構中,隊列的基本知識——
01
隊列
隊列(queue)是一種操作受限的線性表,通過該線性表所存儲的元素具有順序性。它的插入操作只被允許在表的後端進行,而刪除操作則只被允許在表的前端進行。進行插入操作的端被稱爲隊尾,而進行刪除操作的端則被稱爲隊頭。
隊列中的數據以先進先出(First In First Out,FIFO)的方式進出隊列,也就是說先入隊的元素先出隊,而後入隊的元素則後出隊。隊列提供了兩個主要操作:入隊(enqueue),即將某個元素添加到隊列的尾部;出隊(dequeue),即將隊列裏最先添加的元素移出隊列。
此外,隊列一般還具有特定的容量,如果隊列中添加的元素總數超過了容量,則將會導致隊列處於溢出狀態。隊列的實現方式主要有兩種:基於數組和基於鏈表。它們都提供了統一的接口,即入隊和出隊,唯一的區別就是使用了不同的結構來存儲隊列元素。
02
基於數組的隊列
我們先看基於數組的隊列的實現方式,該方式包含的四要素分別是數組、隊頭(head)指針、隊尾(tail)指針以及隊列操作集。
其中,數組用於存放元素,隊頭指針用於指引隊頭位置,隊尾指針用於指引隊尾位置,隊列的核心操作爲入隊和出隊。此外,隊列所存放的元素數量不能超過數組的長度。
❖ 入隊操作
現準備對“the”“monster”“is”“coming”四個字符串分別進行入隊操作,下面我們看看整個過程。
① “the”入隊後,隊尾指針 tail 右移一個位置,指向索引爲 1 的位置。
② “monster”入隊後,隊尾指針 tail 再右移一個位置,指向索引爲 2 的位置。
③ “is”入隊後,隊尾指針 tail 繼續右移一個位置,指向索引爲 3 的位置。
④ “coming”入隊後,隊尾指針 tail 繼續右移一個位置,最終指向索引爲 4 的位置。
我們可以看到在整個過程中隊頭指針 head 都不移動。
❖ 出隊操作
接着再對隊列中的元素進行兩次出隊操作。
① “the”出隊後,隊頭指針 head 右移一個位置,指向索引爲 1 的位置。
② “monster”出隊後,隊頭指針 head 再右移一個位置,指向索引爲 2 的位置。我們可以看到在整個過程中隊尾指針 tail 都不移動。
由於數組的長度是固定的,我們從上面的執行過程可以看到,在不斷進行入隊和出隊操作後兩個指針都將一直往右移,那麼,如果當指針到達數組最後位置時是不是就得重新創建數組呢?答案是不用。
我們可以通過循環機制來重用數組,即把數組看成是首尾相連的,當到達尾部後,下次操作將重新回到首部。前面已經執行了四次入隊操作和兩次出隊操作,現在準備繼續對 6 個“a”進行入隊操作。
在對 5 個“a”執行入隊操作後,隊尾指針 tail 已經到達了數組的尾部。此時,如果再對第 6 個“a”執行入隊操作,則隊尾指針 tail 將重新回到數組首部。
03
基於鏈表的隊列
接着繼續看基於單向鏈表的隊列的實現方式,該方式包含的四要素分別是鏈表、隊頭(head)指針、隊尾(tail)指針以及隊列操作集。
其中,鏈表用於存放元素,隊頭指針用於指引隊頭位置,隊尾指針用於指引隊尾位置,隊列的核心操作爲入隊和出隊。
使用鏈表結構來存放隊列元素時可以不必擔心容量的問題,而基於數組的隊列所存放的元素數量則不能超過數組的長度。初始時,隊頭指針和隊尾指針都不指向任何節點,且鏈表爲 NULL。
❖ 入隊操作
現準備對“the”“monster”“is”“coming”四個字符串分別進行入隊操作,下面我們看看整個過程。
① 創建“the”節點,隊頭指針和隊尾指針都指向該節點。
② 創建“monster”節點。
③ 將“the”節點指向“monster”節點,並移動隊尾指針使其指向“monster”節點。
④ 創建“is”節點,並將“monster”節點指向該節點,隊尾指針指向“is”節點。
⑤ 創建“coming”節點,並將“is”節點指向該節點,隊尾指針指向“coming”節點。
❖ 出隊操作
接着再對隊列中的元素進行兩次出隊操作。
① 取出隊頭元素“the”,然後將隊頭指針前移一位。
② 廢棄“the”節點。
③ 同理,第二次出隊操作先取出“monster”元素,然後將隊頭指針前移一位並廢棄“monster”節點。
好書推薦
《趣學算法》
每種算法都有4~10個實例,共45個大型實例,包括經典的構造實例和實際應用實例,按照問題分析、算法設計、完美圖解、僞代碼詳解、實戰演練、算法解析及優化拓展的流程,講解清楚、通俗易懂。
《趣學數據結構》
採用C++語言編寫,但不使用類,保證學習C語言的人也能看懂。各章包含大量圖解,結合實例講解數據結構的基本操作,力求通俗易懂。
《算法詳解 卷1 算法基礎》
算法詳解系列圖書共有4卷,本書是第一卷——基礎算法。本書共有6章,主要介紹了4個主題,它們分別是漸進性分析和大O表示法、分冶算法和主方法、隨機化算法以及排序和選擇。
學就一個字,堅持就是勝利!
堅持學習都會有收穫。
爲了自己的夢想Offer,
加油吧!