【乾貨】史上最好的排序和數據結構入門

前言

工做已經有一段時間了,有的時候會跟同事們打趣:「若是你讓我如今去手寫一個快速排序,我怕是真的寫不出來」。git

若是不接觸一段時間的算法,真的很容易就忘了。不信?你如今想一想你本身能不能手寫一個堆排序。github

經歷過校招的人都知道,算法和數據結構都是不可避免的。面試

在筆試的時候,最主要的就是靠算法題。像拼多多、頭條這種大公司,上來就來幾道算法題,若是你沒AC出來,面試機會都沒有。算法

在面試(現場面或者視頻面)的時候也會問算法題,難度確定是沒有筆試的時候那麼難的。咱們能夠想象一個場景,一面面試面到一半,面試官讓你反轉二叉樹,問問如今的本身,你還會嗎。後端

不扯遠了,若是還在上大學的同窗能夠先以排序和各類的基本數據結構開始入門。我花了一個星期將八大基礎排序鏈表/二叉樹/棧/隊列製做成一份精美的PDF數組

這份PDF閱讀體驗確定是要比公衆號和各大的博客平臺的文章要好的。PDF內容純手打,有不懂的能夠來問我。微信

下面來簡單介紹一下八大基礎排序和基礎的數據結構,每種排序的思想和基礎的講解和源碼在PDF裏邊有。數據結構

冒泡排序

思路:倆倆交換,大的放在後面,第一次排序後最大值已在數組末尾。由於倆倆交換,須要n-1趟排序(好比10個數,須要9趟排序)學習

代碼實現要點:兩個for循環,外層循環控制排序的趟數,內層循環控制比較的次數每趟事後,比較的次數都應該要減1spa

選擇排序

思路:找到數組中最大的元素,與數組最後一位元素交換。當只有一個數時,則不須要選擇了,所以須要n-1趟排序

代碼實現要點:兩個for循環,外層循環控制排序的趟數,內層循環找到當前趟數的最大值,隨後與當前趟數組最後的一位元素交換

插入排序

思路:將一個元素插入到已有序的數組中,在初始時未知是否存在有序的數據,所以將元素第一個元素當作是有序的。與有序的數組進行比較,比它大則直接放入,比它小則移動數組元素的位置,找到個合適的位置插入。當只有一個數時,則不須要插入了,所以須要n-1趟排序

代碼實現:一個for循環內嵌一個while循環實現,外層for循環控制須要排序的趟數,while循環找到合適的插入位置(而且插入的位置不能小於0)

快速排序

學習快速排序的前提:須要瞭解遞歸

思路:在數組中找一個元素(節點),比它小的放在節點的左邊,比它大的放在節點右邊。一趟下來,比節點小的在左邊,比節點大的在右邊。不斷執行這個操做….

代碼實現:支點取中間,使用L和R表示數組的最小和最大位置。不斷進行比較,直到找到比支點小(大)的數,隨後交換,不斷減少範圍。遞歸L到支點前一個元素(j)。遞歸支點後一個元素(i)到R元素

歸併排序

學習歸併排序的前提:須要瞭解遞歸

思路:將兩個已排好序的數組合併成一個有序的數組。將元素分隔開來,當作是有序的數組,進行比較合併。不斷拆分和合並,直到只有一個元素

代碼實現:在第一趟排序時實質是兩個元素(當作是兩個已有序的數組)來進行合併,不斷執行這樣的操做,最終數組有序,拆分左邊,右邊,合併…

堆排序

學習堆排序的前提:須要瞭解二叉樹

思路:堆排序使用到了徹底二叉樹的一個特性,根節點比左孩子和右孩子都要大,完成一次建堆的操做實質上是比較根節點和左孩子、右孩子的大小,大的交換到根節點上,直至最大的節點在樹頂。隨後與數組最後一位元素進行交換

代碼實現:只要左子樹或右子樹大於當前根節點,則替換。替換後會致使下面的子樹發生了變化,所以一樣須要進行比較,直至各個節點實現父>子這麼一個條件

希爾排序

思路:希爾排序實質上就是插入排序的加強版,希爾排序將數組分隔成n組來進行插入排序,直至該數組宏觀上有序,最後再進行插入排序時就不用移動那麼屢次位置了~

代碼思路:希爾增量通常是gap = gap / 2,只是比普通版插入排序多了這麼一個for循環而已。

基數排序(桶排序)

思路:基數排序(桶排序):將數字切割成個、10、百、千位放入到不一樣的桶子裏,放一次就按桶子順序回收一次,直至最大位數的數字放完~那麼該數組就有序了

代碼實現:先找到數組的最大值,而後根據最大值/10來做爲循環的條件(只要>0,那麼就說明還有位數)。將個位、十位、…分配到桶子上,每分配一次就回收一次

遞歸

遞歸在算法裏邊用得很是很是多,排序算法的快速排序和歸併排序就須要用到遞歸(至少用遞歸來實現是最方便的)。

想要用遞歸必須知道兩個條件:遞歸出口(終止遞歸的條件)和遞歸表達式(規律)

技巧:在遞歸中經常是將問題切割成兩個部分(1和總體的思想),這可以讓咱們快速找到遞歸表達式(規律)

漢羅塔實現:

基本數據結構

鏈表、隊列、二叉樹、棧都是些很是基本的數據結構。針對每種的數據結構都會有對應的算法題,好比說:

  • LeetCode No206:反轉鏈表
  • LeetCode No20:檢驗字符串[]{]}{]{}(這樣的字符串是否有效(對齊)
  • LeetCode No104:樹的最大深度
  • LeetCode No102:層序遍歷樹
  • ...

在校招不求字典樹、紅黑樹、圖這種數據結構要會,但鏈表、隊列、二叉樹、棧這些數據結構的題(LeetCode簡單) 仍是應該要能作出來。

最後

最後想要說明的是,排序算法/數據結構的代碼可能不是最優解,代碼的實現都是以比較容易理解的方式去寫的。幾乎每句代碼都有對應的註釋,應該是能看懂的。

如今已經工做有一段時間了,爲何還來寫最基礎的算法和數據結構呢,緣由有如下幾個:

  • 我是一個對排版有追求的人,若是早期關注個人同窗可能會發現,個人GitHub、文章導航的read.me會常常更換。如今的GitHub導航也不合我心意了(太長了),而且早期的文章,說實話排版也不太行,我決定從新搞一波。
  • 個人文章會分發好幾個平臺,但文章發完了可能就沒人看了,而且圖牀極可能由於平臺的防盜鏈就掛掉了。又由於有不少的讀者問我:」你能不能把你的文章轉成PDF啊?「
  • 我寫過不少系列級的文章,這些文章就幾乎不會有太大的改動了,就很是適合把它們給」持久化「。

基於上面的緣由,我決定把個人系列文章彙總成一個PDF/HTML/WORD文檔。說實話,打造這麼一個文檔花了我很多的時間。爲了防止白嫖,關注個人公衆號回覆「888」便可獲取。

文檔的內容均爲手打,有任何的不懂均可以直接來問我(公衆號有個人聯繫方式)。

上一期的「Servlet」的PDF在公衆號反響仍是挺不錯的,目標是180個在看,雖然還差了一點點才達標,但我仍是把這期給作出來啦!

若是此次在看超過500,那下週再肝一個系列出來。想要看什麼,能夠留言告訴我

涵蓋Java後端全部知識點的開源項目(已有5.8K star):https://github.com/ZhongFuChe...

若是你們想要實時關注我更新的文章以及分享的乾貨的話,微信搜索Java3y

PDF文檔的內容均爲手打,有任何的不懂均可以直接來問我(公衆號有個人聯繫方式)。

相關文章
相關標籤/搜索