小白學排序 十大經典排序算法(動圖)

文章轉自公衆號【機器學習煉丹術】
python


本文的重點排序方法在: 冒泡排序,歸併排序,快速排序,桶排序

算法分類

十種常見排序算法能夠分爲兩大類:算法

比較類排序:經過比較來決定元素間的相對次序,因爲其時間複雜度不能突破O(nlogn),所以也稱爲非線性時間比較類排序。
非比較類排序:不經過比較來決定元素間的相對次序,它能夠突破基於比較排序的時間下界,以線性時間運行,所以也稱爲線性時間非比較類排序。數組

【算法複雜度】數據結構

【相關概念】機器學習

  • 穩定:若是a本來在b前面,而a=b,排序以後a仍然在b的前面。
  • 不穩定:若是a本來在b的前面,而a=b,排序以後 a 可能會出如今 b 的後面。
  • 時間複雜度:對排序數據的總的操做次數。反映當n變化時,操做次數呈現什麼規律。
  • 空間複雜度:是指算法在計算機內執行時所需存儲空間的度量,它也是數據規模n的函數。

冒泡排序(重點)

  • Bubble Sort

【算法描述】ide

  • 比較相鄰的元素。若是第一個比第二個大,就交換它們兩個;
  • 對每一對相鄰元素做一樣的工做,從開始第一對到結尾的最後一對,這樣在最後的元素應該會是最大的數;
  • 針對全部的元素重複以上的步驟,除了最後一個;
  • 重複步驟1~3,直到排序完成。

【動圖演示】
函數

選擇排序

  • Selection Sort
  • 表現最穩定的排序算法之一,由於不管什麼數據進去都是O(n2)的時間複雜度,因此用到它的時候,數據規模越小越好。惟一的好處可能就是不佔用額外的內存空間了吧。理論上講,選擇排序可能也是平時排序通常人想到的最多的排序方法了吧。
    【算法描述】

選擇排序(Selection-sort)是一種簡單直觀的排序算法。它的工做原理:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,而後,再從剩餘未排序元素中繼續尋找最小(大)元素,而後放到已排序序列的末尾。以此類推,直到全部元素均排序完畢。性能

【動圖演示】
學習

插入排序

  • Insertion Sort

【算法描述】ui

通常來講,插入排序都採用in-place在數組上實現。具體算法描述以下:

  • 從第一個元素開始,該元素能夠認爲已經被排序;
  • 取出下一個元素,在已經排序的元素序列中從後向前掃描;
  • 若是該元素(已排序)大於新元素,將該元素移到下一位置;
  • 重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
  • 將新元素插入到該位置後;
  • 重複步驟2~5。

【動圖演示】

歸併排序(重點)

  • Merge Sort
  • 歸併排序是創建在歸併操做上的一種有效的排序算法。該算法是採用分治法(Divide and Conquer)的一個很是典型的應用。將已有序的子序列合併,獲得徹底有序的序列;即先使每一個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱爲2-路歸併。
  • 是遞歸的思想
  • 歸併排序是一種穩定的排序方法。和選擇排序同樣,歸併排序的性能不受輸入數據的影響,但表現比選擇排序好的多,由於始終都是O(nlogn)的時間複雜度。代價是須要額外的內存空間。
    【算法描述】
  • 把長度爲n的輸入序列分紅兩個長度爲n/2的子序列;
  • 對這兩個子序列分別採用歸併排序;
  • 將兩個排序好的子序列合併成一個最終的排序序列。

【動圖演示】

快速排序(重點)

  • Quite Sort
  • 快速排序的基本思想:經過一趟排序將待排記錄分隔成獨立的兩部分,其中一部分記錄的關鍵字均比另外一部分的關鍵字小,則可分別對這兩部分記錄繼續進行排序,以達到整個序列有序。
  • 以前一直覺得快排和二分法有關,可是實際上是分治法的應用。

【算法描述】

快速排序使用分治法來把一個串(list)分爲兩個子串(sub-lists)。具體算法描述以下:

  • 從數列中挑出一個元素,稱爲 「基準」(pivot);
  • 從新排序數列,全部元素比基準值小的擺放在基準前面,全部元素比基準值大的擺在基準的後面(相同的數能夠到任一邊)。在這個分區退出以後,該基準就處於數列的中間位置。這個稱爲分區(partition)操做;
  • 遞歸地(recursive)把小於基準值元素的子數列和大於基準值元素的子數列排序。

【動圖演示】

堆排序(重點)

  • python中sort排序的方法就是堆排序
  • 堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似徹底二叉樹的結構,並同時知足堆積的性質:即子結點的鍵值或索引老是小於(或者大於)它的父節點。

【算法描述】

這個比較複雜。先看動圖而後慢慢細說。

【動圖演示】

【分步詳解】

  • 堆(二叉堆)能夠視爲一棵徹底的二叉樹。徹底二叉樹的一個優秀的性質就是,除了最底層以外,每一層都是滿的

  • 二叉堆通常分爲兩種:最大堆和最小堆。

  • 最大堆 :最大堆中的最大元素在根結點(堆頂);堆中每一個父節點的元素值都大於等於其子結點(若是子節點存在)

  • 最小堆:最小堆中的最小元素出如今根結點(堆頂);堆中每一個父節點的元素值都小於等於其子結點(若是子節點存在)

假設咱們要對目標數組A {57, 40, 38, 11, 13, 34, 48, 75, 6, 19, 9, 7}進行堆排序。

首先第一步和第二步,建立堆,這裏咱們用最大堆;建立過程當中,保證調整堆的特性。從最後一個分支的節點開始進行調整爲最大堆。

如今獲得的最大堆的存儲結構以下:

接着,最後一步,堆排序,進行(n-1)次循環。

這個迭代持續直至最後一個元素即完成堆排序步驟。

【我的理解】

經過堆這個結構,讓隨機兩個數組進行比大小,而後讓獲勝者之間再比大小,這樣就能夠經過複雜都logn獲得一個最大的數字。而後不考慮這個數字,在剩下的數字中重複這個過程。有點相似比賽半決賽,四分之一決賽,八強這樣的感受。

計數排序

  • Counting Sort
  • 計數排序不是基於比較的排序算法,其核心在於將輸入的數據值轉化爲鍵存儲在額外開闢的數組空間中。 做爲一種線性時間複雜度的排序,計數排序要求輸入的數據必須是有肯定範圍的整數。敲黑板!計數排序不是基於比較的,因此是線性時間複雜度,可是速度快的代價就是對輸入數據有限制要求:肯定範圍的整數

【算法描述】

這部分不怎麼用看,直接看動圖就理解了

  • 找出待排序的數組中最大和最小的元素;
  • 統計數組中每一個值爲i的元素出現的次數,存入數組C的第i項;
  • 對全部的計數累加(從C中的第一個元素開始,每一項和前一項相加);
  • 反向填充目標數組:將每一個元素i放在新數組的第C(i)項,每放一個元素就將C(i)減去1。

【動圖演示】

基數排序

  • Radix Sort
  • 基數排序是按照低位先排序,而後收集;再按照高位排序,而後再收集;依次類推,直到最高位。有時候有些屬性是有優先級順序的,先按低優先級排序,再按高優先級排序。最後的次序就是高優先級高的在前,高優先級相同的低優先級高的在前。

【算法描述】

  • 取得數組中的最大數,並取得位數;
  • arr爲原始數組,從最低位開始取每一個位組成radix數組;
  • 對radix進行計數排序(利用計數排序適用於小範圍數的特色);

【動圖演示】

相關文章
相關標籤/搜索