常見算法總結

(一)排序算法

排序算法性能比較

1.插入排序算法

把n個待排序的元素看成為一個有序表和一個無序表。開始時有序表中只包含1個元素滥朱,無序表中包含有n-1個元素,排序過程中每次從無序表中取出第一個元素力试,將它插入到有序表中的適當位置徙邻,使之成為新的有序表,重復n-1次可完成排序過程懂版。

原理:

  • 從第二個元素開始和前面的元素進行比較鹃栽,如果前面的元素比當前元素大,則將前面元素 后移,當前元素依次往前民鼓,直到找到比它小或等于它的元素插入在其后面
  • 然后選擇第三個元素薇芝,重復上述操作,進行插入
  • 依次選擇到最后一個元素丰嘉,插入后即完成所有排序

舉例

數(shù)列[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]需要使用插入排序夯到,我們來看看使用插入排序的詳細步驟:

  • 首先第二個元素99和前面的元素11比較,99>11饮亏,第一輪完了耍贾,列表是 1 [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]
  • 然后,33作為比較元素路幸,和前面的元素99比較荐开,11<33<99交換位置,33插入到11和99之間简肴,列表為 1 [11, 33, 99, 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]
  • 接著晃听,33<69<99交換位置,列表變?yōu)? 1 [11, 33, 69, 99, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]
  • 以此類推砰识,69<77<99,77插入到69和99之間能扒,列表變?yōu)? 1 [11, 33, 69, 77, 99, 88, 55, 11, 33, 36,39, 66, 44, 22]
  • 77<88<99, 88插入到77和99之間,列表變?yōu)? 1 [11, 33, 69, 77, 88, 99, 55, 11, 33, 36,39, 66, 44, 22]
  • 33<55<69<77<88<99,55插入到33和69之間辫狼,列表變?yōu)? 1 [11, 33, 69, 77, 88, 99, 55, 11, 33, 36,39, 66, 44, 22]
  • .......
  • 最終得到列表 1 [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

python實現(xiàn)

def insert_sort(arr):
    # 第一層for表示循環(huán)插入的遍數(shù)
    for i in range(1,len(arr)):
        # 設置當前需要插入的元素
        current = arr[i]
        # 與當前元素比較的比較元素
        pre_index = i - 1
        while pre_index >= 0 and arr[pre_index] > current:
            # 當比較元素大于當前元素則把比較元素后移
            arr[pre_index+1] = arr[pre_index]
            # 往前選擇下一個比較元素
            pre_index -= 1
        # 當比較元素小于當前元素初斑,則將當前元素插入在 其后面
        arr[pre_index+1] = current
    return arr

2.選擇排序

每一次從待排序的數(shù)據(jù)元素中選出最小(或最大)的一個元素膨处,存放在序列的起始位置见秤,所以稱為:選擇排序。

原理

  • 設第一個元素為比較元素灵迫,依次和后面的元素比較秦叛,比較完所有元素找到最小的元素晦溪,將它和第一個元素互換
  • 重復上述操作瀑粥,我們找出第二小的元素和第二個位置的元素互換,以此類推找出剩余最小元素將它換到前面三圆,即完成排序

舉例

數(shù)列[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]需要使用插入排序狞换,我們來看看使用選擇排序的詳細步驟:

1、首先11作為比較元素和列表后面的所有元素比較舟肉,找到最小的11修噪,并放在第一位,第一輪完了路媚,列表是 [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]
2黄琼、然后,99作為比較元素整慎,和后面的元素[33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]作比較脏款,找到最小的11围苫,和第二位元素99交換位置,即第二輪比較完后撤师,列表為 [11, 11, 33 , 69, 77, 88, 55, 99, 33, 36,39, 66, 44, 22]
3剂府、第三輪比較完,22最小剃盾,和第三個元素33交換位置腺占,列表變?yōu)? [11, 11, 22, 69, 77, 88, 55, 99, 33, 36,39, 66, 44, 33]
4、最終得到列表 [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

python實現(xiàn)

def selection_sort(arr):
    # 第一層for表示循環(huán)選擇的遍數(shù)
    for i in range(len(arr)-1):
        # 將起始元素設為最小元素
        min_index = i
        # 第二層for表示最小元素和后面的元素逐個比較
        for j in range(i+1,len(arr)):
            if arr[j] < arr[min_index]:
                # 如果當前元素比最小元素小痒谴,則把當前元素角標記為最小元素角標
                min_index = j
        # 查找一遍后將最小元素與起始元素互換
        temp = arr[min_index]
        arr[min_index]=arr[i]
        arr[i] = temp
    return arr

3.冒泡排序

重復地走訪過要排序的元素列衰伯,依次比較兩個相鄰的元素,一層一層的將較大的元素往后移動积蔚,其現(xiàn)象和氣泡在上升過程中慢慢變大類似嚎研,故成為冒泡排序。

原理

  • 從第一個和第二個開始比較库倘,如果第一個比第二個大临扮,則交換位置,然后比較第二個和第三個教翩,逐漸往后
  • 經(jīng)過第一輪后最大的元素已經(jīng)排在最后杆勇,所以重復上述操作的話第二大的則會排在倒數(shù)第二的位置。
  • 那重復上述操作n-1次即可完成排序饱亿,因為最后一次只有一個元素所以不需要比較

舉例

舉個例子蚜退,假設我現(xiàn)在有一個數(shù)列需要使用冒泡來排序 [11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22],我們來看看使用冒泡的詳細步驟:

  • 首先11和99比較大小彪笼,99大钻注,99繼續(xù)和后面的作比較,直到最后一個元素配猫,第一輪完了幅恋,列表是 [11, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22, 99]
  • 然后,重復第一輪操作泵肄,即第二輪比較列表是 [11, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22, 99]捆交,
  • 比較完后,列表為 [11, 33 , 69, 77, 55, 11, 33, 36,39, 66, 44, 22, , 88腐巢,99]
  • 以此類推品追,最終得到列表 [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

python實現(xiàn)

def bubble_sort(arr):
    # 第一層for表示循環(huán)的遍數(shù)
    for i in range(len(arr)-1):
        # 第二層for表示具體比較哪兩個元素
        for j in range(len(arr)-1-i):
            if a[j] > a[j+1]:
                # 如果前面的大于后面的,則交換這兩個元素的位置
                temp = a[j]
                a[j] = a[j+1]
                a[j+1] = temp
    return arr

4.快速排序(重點)

通過一趟排序將要排序的數(shù)據(jù)分割成獨立的兩部分冯丙,其中一部分的所有數(shù)據(jù)都比另外一部分的所有數(shù)據(jù)都要小肉瓦,然后再按此方法對這兩部分數(shù)據(jù)分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數(shù)據(jù)變成有序序列泞莉。

原理

  • 在數(shù)列之中洁墙,選擇一個元素作為”基準”(pivot),或者叫比較值戒财。
  • 數(shù)列中所有元素都和這個基準值進行比較热监,如果比基準值小就移到基準值的左邊,如果比基準值大就移到基準值的右邊
  • 以基準值左右兩邊的子列作為新數(shù)列饮寞,不斷重復第一步和第二步孝扛,直到所有子集只剩下一個元素為止。

舉例

舉個例子幽崩,假設我現(xiàn)在有一個數(shù)列需要使用快排來排序:[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]苦始,我們來看看使用快排的詳細步驟:

  • 選取中間的66作為基準值(基準值可以隨便選)
  • 數(shù)列從第一個元素11開始和基準值66進行比較,小于基準值慌申,那么將它放入左邊的分區(qū)中陌选,第二個元素99比基準值66大,把它放入右邊的分區(qū)中蹄溉。
  • 然后依次對左右兩個分區(qū)進行再分區(qū)咨油,直到最后只有一個元素
  • 分解完成再一層一層返回,返回規(guī)則是:左邊分區(qū)+基準值+右邊分區(qū)

python實現(xiàn)

def quick_sort(arr):
    if len(arr) < 2:
        return arr
    mid = arr[len(arr)//2]
    left = []
    right = []
    arr.remove(mid)
    for item in arr:
        if item >= mid:
            right.append(item)
        else:
            left.append(item)
    return quick_sort(left) + [mid] + quick_sort(right)

5.希爾排序

先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序柒爵,待整個序列中的記錄“基本有序”時役电,再對全體記錄進行依次直接插入排序。

原理

希爾排序
  • 計算一個增量(間隔)值
  • 對元素進行增量元素進行比較棉胀,比如增量值為7法瑟,那么就對0,7,14,21…個元素進行插入排序
  • 然后對1,8,15…進行排序,依次遞增進行排序
  • 所有元素排序完后唁奢,縮小增量比如為3霎挟,然后又重復上述第2,3步
  • 最后縮小增量至1時麻掸,數(shù)列已經(jīng)基本有序酥夭,最后一遍普通插入即可

舉例

舉個例子,假設我現(xiàn)在有一個數(shù)列需要使用快排來排序:[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]论笔,我們來看看使用希爾排序的詳細步驟:

  • 首先采郎,gap = length / 2=7,數(shù)組分為7組
    [11, 11],[ 99 , 33], [33, 36], [69, 39],[ 77, 66],[88, 44], [55, 22]
  • 然后狂魔,對7組分別插入排序,像33,39,66,44,22這些元素被調(diào)到前面淫痰,
    [11, 11],[ 33 , 99], [33, 36], [39, 69],[ 66, 77],[44, 88], [22, 55]
  • 接著最楷,數(shù)組變?yōu)?br> [11, 11,33 , 99, 33, 36, 39, 69, 66, 77,44, 88, 22, 55]
    gap = length / 2=3,數(shù)組分為3組,
    [11,99,39,77,22],[11,33,69,44,55],[33,36,66,88]
  • 以此類推籽孙,gap = length / 2=1列表變?yōu)?br> [11,22,39,77,99,11,33,44,55,69,33,36,66,88]
  • 最終對數(shù)組微調(diào)烈评,得到列表
    [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

python實現(xiàn)

def sheel_sort(arr):
    gap = len(arr) // 2
    while gap > 0:
        for i in range(gap,len(arr)):
            j = i
            current = a[i]
            while j - gap >=0 and current < arr[j - gap]:
                arr[j] = arr[j - gap]
                j -= gap
            a[j] = current
        gap = gap //2
    return arr

6.歸并排序

歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。歸并排序適用于子序列有序的數(shù)據(jù)排序犯建。

原理

  • 將一個序列從中間位置分成兩個序列糠爬;
  • 在將這兩個子序列按照第一步繼續(xù)二分下去最疆;
  • 直到所有子序列的長度都為1,也就是不可以再二分截止。這時候再兩兩合并成一個有序序列即可烁设。


    歸并排序

舉例

舉個例子,假設我現(xiàn)在有一個數(shù)列需要使用快排來排序:[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]叉庐,我們來看看使用歸并排序的詳細步驟:

1.對以下數(shù)組進行歸并排序: 
[11, 99, 33 , 69, 77, 88, 55, 11, 33, 36,39, 66, 44, 22]

  1. 首先宏多,進行數(shù)組分組,即
    [11, 99, 33 , 69, 77, 88, 55], [ 11, 33, 36,39, 66, 44, 22]
    [11, 99, 33] , [69, 77, 88, 55], [ 11, 33, 36], [39, 66, 44, 22]
    [11], [99, 33] , [69, 77], [88, 55],[ 11], [33, 36],[39, 66], [44, 22]
    直到所有子序列的長度都為1嗦随,也就是不可以再二分截止列荔。
    [11], [99], [33] , [69], [77], [88], [55],[ 11], [33], [36],[39], [66], [44], [22]
  2. 這時候再兩兩合并成一個有序序列即可。
    [11],[33,99],[69,77],[55,88],[11],[33,36],[39,66],[22,44]
    [11,33,99],[55,69,77,88],[11,33,36],[22,39,44,66]
    [11,33,55,69,77,88,99],[11,22,33,36,39,44,66]
    4枚尼、最終排序
    [11, 11, 22, 33, 33, 36, 39, 44, 55, 66, 69, 77, 88, 99]

python實現(xiàn)

def merge_sor(arr):
    if len(arr) == 1:
        return arr
    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]
    return merge(merge_sort(left),merge_sort(right))

def merge(left,right):
    result = []
    while len(left)>0 and len(right) > 0:
        if left[0] >= right[0]:
            result.append(left.pop(0))
        else:
            result.append(right.pop(0))
    result += left
    result += right
    return result
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贴浙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子署恍,更是在濱河造成了極大的恐慌悬而,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锭汛,死亡現(xiàn)場離奇詭異笨奠,居然都是意外死亡,警方通過查閱死者的電腦和手機唤殴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門般婆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朵逝,你說我怎么就攤上這事蔚袍。” “怎么了配名?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵啤咽,是天一觀的道長。 經(jīng)常有香客問我渠脉,道長宇整,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任芋膘,我火速辦了婚禮鳞青,結果婚禮上霸饲,老公的妹妹穿的比我還像新娘。我一直安慰自己臂拓,他們只是感情好厚脉,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胶惰,像睡著了一般傻工。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上孵滞,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天中捆,我揣著相機與錄音,去河邊找鬼剃斧。 笑死轨香,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的幼东。 我是一名探鬼主播臂容,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼根蟹!你這毒婦竟也來了脓杉?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤简逮,失蹤者是張志新(化名)和其女友劉穎球散,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體散庶,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡蕉堰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了悲龟。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屋讶。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖须教,靈堂內(nèi)的尸體忽然破棺而出皿渗,到底是詐尸還是另有隱情,我是刑警寧澤轻腺,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布乐疆,位于F島的核電站,受9級特大地震影響贬养,放射性物質發(fā)生泄漏挤土。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一煤蚌、第九天 我趴在偏房一處隱蔽的房頂上張望耕挨。 院中可真熱鬧细卧,春花似錦尉桩、人聲如沸筒占。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翰苫。三九已至,卻和暖如春这橙,著一層夾襖步出監(jiān)牢的瞬間奏窑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工屈扎, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留埃唯,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓鹰晨,卻偏偏與公主長得像墨叛,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子模蜡,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 目前能ping通的IP:216.58.193.51 59.18.44.245 59.18.44.53 59.18....
    StevenZack閱讀 1,713評論 0 0
  • 一漠趁、 選擇排序:1、首先在未排序序列中找到最腥碳病(大)元素闯传,存放到排序序列的起始位置2、再從剩余未排序元素中繼續(xù)尋找...
    woniu閱讀 186評論 0 0
  • 一個女孩喜歡男孩卤妒,可是男孩卻不回甥绿,大概他太忙還是故意不回。
    青春荒唐我不負閱讀 56評論 0 0
  • 2月份的我終于打算不再創(chuàng)業(yè)了则披,準備安安心心的找一個工作共缕,開始人生的另外一段旅程。在這之前收叶,也準備帶著母親大人去旅行...
    Susan曾閱讀 645評論 6 7
  • 最近一日堂竟,去一火鍋店吃火鍋,看到宣傳單上寫道玻佩,隨手拍用餐的兩張圖片發(fā)朋友圈出嘹,就可以得到店家贈送的一份精美水果...
    格致先行fgl閱讀 684評論 0 0