1. 程式人生 > >找工作知識儲備(3)---從頭說12種排序演算法:原理、圖解、動畫視訊演示、程式碼以及筆試面試題目中的應用

找工作知識儲備(3)---從頭說12種排序演算法:原理、圖解、動畫視訊演示、程式碼以及筆試面試題目中的應用

作者:寒小陽

0、前言    

 從這一部分開始直接切入我們計算機網際網路筆試面試中的重頭戲演算法了,初始的想法是找一條主線,比如資料結構或者解題思路方法,將博主見過做過整理過的演算法題逐個分析一遍(博主當年自己學演算法就是用這種比較笨的刷題學的,囧),不過又想了想,演算法這東西,博主自己學的過程中一直深感,基礎還是非常重要的,很多難題是基礎類資料結構和題目的思想綜合發散而來。比如說作為最基本的排序演算法就種類很多,而事實上筆試面試過程中發現掌握的程度很一般,有很多題目,包括很多演算法難題,其母題或者基本思想就是基於這些經典演算法的,比如說快排的partition演算法,比如說歸併排序中的思想,比如說桶排序中桶的思想。


        這裡對筆試面試最常涉及到的12種排序演算法(包括插入排序、二分插入排序、希爾排序、選擇排序、氣泡排序、雞尾酒排序、快速排序、堆排序、歸併排序、桶排序、計數排序和基數排序)進行了詳解。每一種演算法都有基本介紹、演算法原理分析、圖解/flash演示/視訊演示、演算法程式碼、筆試面試重點分析、筆試面試題等板塊,希望能幫助大家真正理解這些排序演算法,並能使用這些演算法的思想解決一些題。不多說了,下面就進入正題了。

一、插入排序

1)演算法簡介

        插入排序(Insertion Sort)的演算法描述是一種簡單直觀的排序演算法。它的工作原理是通過構建有序序列,對於未排序資料,在已排序序列中從後向前掃描,找到相應位置並插入

。插入排序在實現上,通常採用in-place排序(即只需用到O(1)的額外空間的排序),因而在從後向前掃描過程中,需要反覆把已排序元素逐步向後挪位,為最新元素提供插入空間。

2)演算法描述和分析

    一般來說,插入排序都採用in-place在陣列上實現。具體演算法描述如下:

    1、從第一個元素開始,該元素可以認為已經被排序

    2、取出下一個元素,在已經排序的元素序列中從後向前掃描

    3、如果該元素(已排序)大於新元素,將該元素移到下一位置

    4、重複步驟3,直到找到已排序的元素小於或者等於新元素的位置

    5、將新元素插入到該位置後

    6、重複步驟2~5

        如果目標是把n個元素的序列升序排列,那麼採用插入排序存在最好情況和最壞情況。最好情況就是,序列已經是升序排列了,在這種情況下,需要進行的比較操作需(n-1)次即可。最壞情況就是,序列是降序排列,那麼此時需要進行的比較共有n(n-1)/2次。插入排序的賦值操作是比較操作的次數減去(n-1)次。平均來說插入排序演算法複雜度為O(n^2)。因而,插入排序不適合對於資料量比較大的排序應用。但是,如果需要排序的資料量很小,例如,量級小於千,那麼插入排序還是一個不錯的選擇。 插入排序在工業級庫中也有著廣泛的應用,在STL的sort演算法和stdlib的qsort演算法中,都將插入排序作為快速排序的補充,用於少量元素的排序(通常為8個或以下)。

3)演算法圖解、flash演示、視訊演示

圖解:


Flash:

視訊:插入排序舞蹈

4)演算法程式碼

  1. void insertion_sort(int array[], int first, int last)  
  2.  {  
  3.         int i,j;  
  4.         int temp;  
  5.         for (i = first+1; i<=last;i++)  
  6.         {  
  7.                 temp = array[i];  
  8.                 j=i-1;  
  9.                 //與已排序的數逐一比較,大於temp時,該數後移
  10.                 while((j>=first) && (array[j] > temp))  //當first=0,j迴圈到-1時,由於[[短路求值]],不會運算array[-1]
  11.                 {  
  12.                         array[j+1] = array[j];  
  13.                         j--;  
  14.                 }  
  15.                 array[j+1] = temp;      //被排序數放到正確的位置
  16.         }  
  17.  }  

 5)考察點,重點和頻度分析

        把插入排序放在第一個的原因是因為其出現的頻度不高,尤其是這裡提到的直接排序演算法,基本在筆試的選擇填空問時間空間複雜度的時候才可能出現。畢竟排序速度比較慢,因此演算法大題中考察的次數比較比較少。

6)筆試面試例題

例題1、

請寫出連結串列的插入排序程式

  1. template<typename T>  
  2. struct list_node  
  3. {  
  4.     struct list_node<T> *next;  
  5.     T value;  
  6. };  
  7. template<typename T>  
  8. struct _list  
  9. {  
  10.     struct list_node<T> *head;  
  11.     int size;  
  12. };  
  13. template<typename T>  
  14. void SortLink(struct _list<T> * link) {  
  15.     struct list_node<T> *pHead,*pRear,*p,*tp;  
  16.     if (!link) return;  
  17.     for (pHead=link->head,pRear=0;pHead;pHead=pHead->next) {  
  18.         for (tp=pHead,p=pHead->next;p;tp=p,p=p->next)  
  19.             if (pHead->value>=p->value)  
  20.                 tp->next=p->next,p->next=pHead,pHead=p,p=tp;  
  21.         if (!pRear) link->head=pHead;  
  22.         else pRear->next=pHead;  
  23.         pRear=pHead;  
  24.     }  
  25. }  

例題2、

下列排序演算法中最壞複雜度不是n(n-1)/2的是 D

A.快速排序     B.氣泡排序   C.直接插入排序   D.堆排序

二、二分插入排序

1)演算法簡介

       二分(折半)插入(Binary insert sort)排序是一種在直接插入排序演算法上進行小改動的排序演算法。其與直接排序演算法最大的區別在於查詢插入位置時使用的是二分查詢的方式,在速度上有一定提升。

2)演算法描述和分析

    一般來說,插入排序都採用in-place在陣列上實現。具體演算法描述如下:

    1、從第一個元素開始,該元素可以認為已經被排序

    2、取出下一個元素,在已經排序的元素序列中二分查詢到第一個比它大的數的位置

    3、將新元素插入到該位置後

    4、重複上述兩步

        1)穩定

        2)空間代價:O(1)

        3)時間代價:插入每個記錄需要O(log i)比較,最多移動i+1次,最少2次。最佳情況O(n log n),最差和平均情況O(n^2)

        二分插入排序是一種穩定的排序。當n較大時,總排序碼比較次數比直接插入排序的最差情況好得多,但比最好情況要差,所元素初始序列已經按排序碼接近有序時,直接插入排序比二分插入排序比較次數少。二分插入排序元素移動次數與直接插入排序相同,依賴於元素初始序列。

3)演算法圖解、flash演示、視訊演示

圖解:

                                                          

視訊:二分插入排序

4)演算法程式碼

  1. void BinInsertSort(int a[], int n)   
  2. {   
  3.         int key, left, right, middle;   
  4.         for (int i=1; i<n; i++)   
  5.         {   
  6.                 key = a[i];   
  7.                 left = 0;   
  8.                 right = i-1;   
  9.                 while (left<=right)   
  10.                 {   
  11.                         middle = (left+right)/2;   
  12.                         if (a[middle]>key)   
  13.                                 right = middle-1;   
  14.                         else
  15.                                 left = middle+1;   
  16.                 }   
  17.                 for(int j=i-1; j>=left; j--)   
  18.                 {   
  19.                         a[j+1] = a[j];   
  20.                 }   
  21.                 a[left] = key;          
  22.         }   
  23. }  

 5)考察點,重點和頻度分析

        這個排序演算法在筆試面試中出現的頻度也不高,但畢竟是直接排序演算法的一個小改進演算法,同時二分查詢又是很好的思想,有可能會在面試的時候提到,演算法不難,留心一下就會了。

6)筆試面試例題

例題1、

下面的排序演算法中,初始資料集的排列順序對演算法的效能無影響的是(B)

A、二分插入排序         B、堆排序         C、氣泡排序            D、快速排序

例題2、

寫出下列演算法的時間複雜度。

(1)氣泡排序;(2)選擇排序;(3)插入排序;(4)二分插入排序;(5)快速排序;(6)堆排序;(7)歸併排序;

三、希爾排序

1)演算法簡介

希爾排序,也稱遞減增量排序演算法,因DL.Shell於1959年提出而得名,是插入排序的一種高速而穩定的改進版本。

2)演算法描述

    1、先取一個小於n的整數d1作為第一個增量,把檔案的全部記錄分成d1個組。

    2、所有距離為d1的倍數的記錄放在同一個組中,在各組內進行直接插入排序。

    3、取第二個增量d2<d1重複上述的分組和排序,

    4、直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有記錄放在同一組中進行直接插入排序為止。

          希爾排序的時間複雜度與增量序列的選取有關,例如希爾增量時間複雜度為O(n^2),而Hibbard增量的希爾排序的時間複雜度為O(N^(5/4)),但是現今仍然沒有人能找出希爾排序的精確下界。

3)演算法圖解、flash演示、視訊演示

圖解:





Flash:

視訊:希爾排序Shell Sort 舞蹈

4)演算法程式碼

  1. #include <stdio.h>
  2. int main()  
  3. {  
  4.      constint n = 5;  
  5.      int i, j, temp;   
  6.      int gap = 0;  
  7.      int a[] = {5, 4, 3, 2, 1};   
  8.      

    相關推薦

    [置頂] 工作知識儲備(3)---從頭12排序演算法原理圖解動畫視訊演示程式碼以及筆試面試題目應用

    分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

    工作知識儲備(3)---從頭12排序演算法原理圖解動畫視訊演示程式碼以及筆試面試題目應用

    作者:寒小陽 0、前言      從這一部分開始直接切入我們計算機網際網路筆試面試中的重頭戲演算法了,初始的想法是找一條主線,比如資料結構或者解題思路方法,將博主見過做過整理過的演算法題逐個分析一遍(博主當年自己學演算法就是用這種比較笨的刷題學的,

    ] 工作知識儲備(2)---陣列字串那些經典演算法最大子序列和,最長遞增子序列,最長公共子串,最長公共子序列,字串編輯距離,最長不重複子串,最長迴文子串

    作者:寒小陽 時間:2013年9月。 0、前言         這一部分的內容原本是打算在之後的字串或者陣列專題裡面寫的,但看著目前火熱進行的各家網際網路公司筆試面試中,出現了其中的一兩個內容,就隨即將這些經典問題整理整理,單寫一

    12排序演算法原理圖解動畫視訊演示程式碼以及筆試面試題目應用

    0、前言      從這一部分開始直接切入我們計算機網際網路筆試面試中的重頭戲演算法了,初始的想法是找一條主線,比如資料結構或者解題思路方法,將博主見過做過整理過的演算法題逐個分析一遍(博主當年自己學演算法就是用這種比較笨的刷題學的,囧),不過又想了想,演算法這東西,博主自己學的過程中一直深感,基礎

    12排序演算法詳解

    作者:寒小陽 0、前言      從這一部分開始直接切入我們計算機網際網路筆試面試中的重頭戲演算法了,初始的想法是找一條主線,比如資料結構或者解題思路方法,將博主見過做過整理過的演算法題逐個分析一遍(博主當年自己學演算法就是用這種比較笨的刷題學的,

    java實現12排序演算法

    Java實現的12種排序 2019-01-05       一.氣泡排序及其實現 二.希爾排序及其實現 三.插入排序及其實現 四.插入排序及其實現 五.快速排序及其實現 六.合併排序及其實現 七.計數排序及其實現 八.基數排序及其實現 九. 

    【python資料結構與演算法】幾排序演算法氣泡排序快速排序

    以下排序演算法,預設的排序結果是從小到大。 一.氣泡排序: 1.氣泡排序思想:越大的元素,就像越大的氣泡。最大的氣泡才能夠浮到最高的位置。 具體來說,即,氣泡排序有兩層迴圈,外層迴圈控制每一輪排序中操作元素的個數——氣泡排序每一輪都會找到遍歷到的元素的最大值,並把它放在最後,下一輪排序時

    C語言單鏈表的3排序演算法,插入排序,氣泡排序,選擇排序

    //插入排序 stu *view_sort_math(stu *head)   {       struct student *first;     struct student *t;       struct student *p;        struct student *q;        fi

    Java常用的八排序演算法程式碼實現(三)排序計數排序基數排序

    三種線性排序演算法:桶排序、計數排序、基數排序 線性排序演算法(Linear Sort):這些排序演算法的時間複雜度是線性的O(n),是非比較的排序演算法 桶排序(Bucket Sort)   將要排序的資料分到幾個有序的桶裡,每個桶裡的資料再單獨進行排序,桶內排完序之後,再把桶裡的

    Java常用的八排序演算法程式碼實現(二)歸併排序快速排序

    注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort):   分而治之,遞迴實現   如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了   歸併排序是穩定的排序演算法,時間

    排序演算法

    一:插入排序 二:選擇排序 三:氣泡排序 四:歸併排序 五:快速排序   #include <iostream> #include<vector> #include<algorithm> #include<string>

    用java實現七排序演算法

     很多時候,聽別人在討論快速排序,選擇排序,氣泡排序等,都覺得很牛逼,心想,臥槽,排序也分那麼多種,就覺得別人很牛逼呀,其實不然,當我們自己去了解學習後發現,並沒有想象中那麼難,今天就一起總結一下各種排序的實現原理並加以實現。                         -WH 一、文章

    6分鐘演示,15排序演算法視訊

        github:https://github.com/bingmann/sound-of-sorting 排序之聲 - “Audibilization”和排序演算法的視覺化:http://panthema.net/2013/sound-of-sorting/ 視訊:https

    排序演算法的時間複雜度複雜度

    https://www.cnblogs.com/dll-ft/p/5861210.html 轉載 1、穩定性 歸併排序、氣泡排序、插入排序。基數排序是穩定的 選擇排序、快速排序、希爾排序、堆排序是不穩定的   2、時間複雜度 最基礎的四個演算法:冒泡、選擇

    php四基礎演算法冒泡,選擇,插入和快速排序程式碼練習

    function maopao($arr,$len) { for($i=1;$i<$len;$i++) { for($j=0;$j<$len-$i;$j++) { if($arr[$j]>$arr[$j+1])

    python實現的八排序演算法

    1.快速排序 排序思想: 1.從數列中挑出一個元素,稱為"基準"(pivot) 2.重新排序數列,所有比基準值小的元素放在基準前面,比基準大的元素放在基準後面。在這個分割槽結束之後,該基準就處於數列的中間位置,這就是分割槽操作。 3.遞迴地把小於基準的子數列和大於基準的子數列排序

    Python三排序演算法的執行速度對比(快速排序氣泡排序選擇排序)

    最近看了一下快速排序演算法,據說速度比其他的排序演算法快,於是寫了三個排序演算法對比一下,分別是氣泡排序,快速排序,選擇排序,以下是三個排序演算法的程式碼: 氣泡排序   BubbleSort.py # -*- coding:utf8 -*- def Sort(list

    排序演算法,記錄一下

    個人也就會四種排序(bubble,select,insert,quick),哈哈,看官大人可能有點失望。自己也看過幾種,不過一直沒寫過其他的,就記錄下這四種吧。 程式碼均可直接通過編譯。各種版本實現都有出入,不過思想都是一樣。工作這麼久還沒有一次性完全寫正確過,功力還是差點。 #includ

    5 排序演算法--C語言連結串列

    原始碼地址 GitHub:https://github.com/GYT0313/C-DataStructure/blob/master/sortIn5.c 包括: 氣泡排序 快速排序 選擇排序 插入排序 希爾排序 執行: 注意:

    超炫的6排序演算法的Python實現

    1.氣泡排序 思路:遍歷列表,每一輪每次比較相鄰兩項,將無序的兩項交換,下一輪遍歷比前一輪比較次數減1。 def bubble_sort(a_li