上一周的幾篇文章主要分享了有關數據結構相關的知識,有興趣的可以翻回去看一下。前面我也說到:數據結構和算法是一對"相愛相殺的"組合,所以接下來要分享下我個人對於一些算法的理解和實現。本文將主要分享基礎的查找和排序(代碼基於python)
既然要開始分享算法,那必然要先介紹下算法相關的一些基本術語,如下。
01基本術語
穩定性
概念:如果值相同的元素在排序前後保證著排序前的相對位置,則稱為穩定的排序,反之則為不穩定排序,如圖
主流衡量算法好壞的方法
大O表示法
它表示隨著輸入大小n 的增大,算法執行需要的時間的增長速度可以用 f(n) 來描述,f(n)就是問題規模n的某個函數
幾個經典排序的時間複雜度(平均情況下)和穩定性
冒泡 - O(n) - 穩定排序插入 - O(n) - 穩定排序選擇 - O(n) - 不穩定排序快速 - O(nlog2(n)) - 不穩定排序歸併 - O(nlog2(n)) - 穩定排序術語基本上就差不多了,接下來開始分享算法。
02查找算法
需求:從給定的數組中尋找某個數據
暴力法
暴力法是最符合正常人邏輯的一種算法,總結來說就是窮舉所有可能,然後從所有可能中尋找結果,但是時間複雜度一般比較高。
二分查找
官方定義
二分查找也稱折半查找(Binary Search),它是一種效率較高的查找方法。但是,折半查找要求線性表必須採用順序存儲結構,而且表中元素按關鍵字有序排列
理解
代碼實現
03排序算法
算法基本上是面試必問的問題之一了。連最基礎的排序算法也有n多種不同的實現,何況還有更複雜的包括遞歸,動態規劃等等。下面將主要分享幾種非常基礎但是重要的排序算法。
04冒泡排序
冒泡排序是最最最好理解的一種排序算法,但是只會下面的第一種可能不夠,因為面試官很可能會問你有沒有什麼可優化的空間。
冒泡理解
想像一下河裡的水泡,都是由小到大慢慢浮出水面的一種狀態。
是指將列表中的數據從第一個開始,兩兩比較,保證較大的元素排在較小元素的後面,以此類推,直至整個列表中最大的數據已經被放置在了列表的最後一個位置上結束重複上面的步驟,這次比較完的結果應該是列表中倒數第二個數據為次大值,以此類推直至所有元素有序(外部控制循環的次數,為 len(list) - 1次)
實現
最粗暴的方式
簡單優化版(減少列表有序部分的比較次數)
比如一個無序列表的幾項在調整部分排序後,已經有序了,那麼此時就不需要再進行比較了,程序退出即可。
繼續優化
記錄最後一次交換元素的位置,主要在於後面已經有序的部分不在進行比較
05選擇排序(O(n))
選擇排序的原理
一般來講,每次循環默認選定列表第一個位置為當前列表最大值,將此位置的值和後面的值做比對,如果發現更大的值,則記錄該值的位置,直到遍歷到列表末尾,將末尾的值和最大位置的值交換,這樣最大的值便出現在列表的最後一個位置,以此類推。
所以選擇排序是基於數據的索引進行排序。
選擇排序的代碼實現
06插入排序
插入排序的原理
將原列表想像成兩部分,前面是已經排好序的,後面是亂序的,依次將亂序部分的每一個數據都和前面排好序的部分進行比較,插入到相應的位置
算法思路
最開始,將列表第一個數據加入到前面部分,這時原列表就可看作第一個數據(排好序部分)和剩下的數據(未排序部分)兩部分,並同時將第二個數據(未排序中的第一個數據)和第一個數據(排好序的最後一個數據)進行比對,根據大小插入到相應的位置,此時有兩個數據已經有序然後將第三個數據(未排序中的第一個數據)和前兩個數據(已經有序的兩個)相比較,並移動比自身更大的數據,排序,這樣便排好3個數據以此類推,直到整個後面部分(未排序)的數據都添加到前面部分(有序)中
插入排序代碼實現
07總結
本片主要分享了最基礎的關於查找和排序相關算法的原理和實現,包括二分查找,冒泡排序,選擇排序,以及插入排序,這些屬於入門級的算法,後面文章會繼續分享基於遞歸的經典算法"歸併排序以及快速排序"等稍微複雜一點點的排序算法。
我是一名奮戰在編程界的pythoner,工作中既要和數據打交道,也要和erp系統,web網站保持友好的溝通……時不時的會分享一些提高效率的編程小技巧,在實際應用中遇到的問題以及解決方案,或者源碼的閱讀等等,歡迎大家一起來討論!如果覺得寫得還不錯,歡迎關注點讚,謝謝。