(轉)八大排序(含動圖)

原文:http://blog.csdn.net/u010850027/article/details/49362279  


排序是數據處理中一種很重要也很常用的運算,一般情況下,排序操作在數據處理過程中要花費許多時間,爲了提高計算機的運行效率,我們提出並不斷改進各種各樣的排序算法,這些算法也從不同角度展示了算法設計的重要原則和技巧。在小編的世界中,排序就是對一組雜亂無章的數據進行各種各樣的排序,使其從無序的數據變成有序的數據,排序的目的就是爲了方便查找,分內部排序和外部排序。如下圖所示:

          

        今天這篇博文,小編主要簡單的總結一下內部排序,讓我們一起來揭開排序的神祕面紗,看看他們到底按照怎樣的規則進行一一排序的,總的來說,在排序中,有三種基本的排序,選擇排序、插入排序和交換排序,其餘的排序都是在這三種基本的排序上演化或者是優化而來的,首先我們來看選擇排序。

         選擇排序—直接選擇排序

         選擇排序包括兩種,分別是直接選擇排序和堆排序,選擇排序的基本思想是每一次在n-i+1(i=1,2,3,…,n-1)個記錄中選取鍵值最小的記錄作爲有序序列的第i個記錄,首先我們來看選擇排序中的第一種排序—直接選擇排序。直接選擇排序的基本思想是,在第i次選擇操作中,通過n-i次鍵值間比較,從n-i+1個記錄中選出鍵值最小的記錄,並和第i(1小於等於1小於等於n-1)個記錄交換,說了基本思想之後,趕腳還是稀裏糊塗的,我們來看一下直接選擇排序具體是如何排序的,如下圖所示:‘

        

       如上所示的一組序列爲8、5、2、6、9、3、1、4、0、7,首先我們在這個裏面選取一個最小的數當然最大的也可以,具體根據要求來進行選擇,我們以從小到大的順序進行排列,首先,我們選取一個最小的數字0,0和8進行交互位置,經過第一次選擇之後,序列的順序變成0、5、2、6、9、3、1、4、8、7,接着進行第二次選擇,再選擇一個最小的數字1,1和5交互位置,依次類推,直到該序列是有序序列爲止。

        選擇排序—堆排序

        接着我們來看選擇排序中的另一種排序—堆排序,由上面的直接選擇排序分析,我們知道,在n個鍵值中選出最小值,至少進行n-1次比較,然而繼續在剩餘的n-1個鍵值中選擇出第二個小的值是否一定要進行n-2次比較呢?如果能利用錢n-1次比較所得信息,是否可以減少以後各次選中的次數比較呢?基本這個,我們來看堆排序,堆排序是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,利用數組的特點快速定位指定索引的元素。堆分爲大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在數組的非降序排序中,需要使用的就是大根堆,因爲根據大根堆的要求可知,最大的值一定在堆頂。我們來看堆排序到底是怎麼排的呢?下面我們以小堆爲例,如下圖所示:


         如上圖所示的序列是6、5、3、1、8、7、2、4,我們首先將其構建成一個堆,通過構建我們發現這個時候的序列爲8、6、7、4、5、3、2、1,接着,我們1和8進行比較,發現1小於8,所以交互位置,刨去8,這個時候的序列爲1、6、7、4、5、3、2,發現7比1大,交互位置,1比3小,交互位置,構成的是一個大頂堆了,這個時候,只需要7跟二叉樹的最後一個節點進行比較即可,刨去7,依次類推,小編這裏用語言描述的不是很準確,沒有立體感,很難進行想象,小夥伴可以仔細看上面的這個動態圖是如何進行堆排序的。

         插入排序—直接插入排序

         常用的插入排序有兩種,直接插入排序和希爾排序,首先我們來看直接插入排序,直接插入排序是一種簡單的排序方法,她的基本思想是依次將每個記錄插入到一個已排好序的有序表中去,從而得到一個新的、記錄數增加1的有序表,就好比圖書館整理圖書的這麼一個過程,接着我們來看一下,直接插入排序的具體排序,如下圖所示:

         

        如上圖所示的一組序列爲6、5、3、1、8、7、2、4,首先6和5比較,6比5大交互位置,接着3和5比較,6比3大交互位置,3和5比,交互位置,現在的序列就是3、5、6、1、8、7、2、4,這個時候要把1插入到序列中,首先在徐磊中查找以確定1所應插入的位置,然後就行插入操作,從6起向左順序查找,由於1小於3,所以1插入的位置就是3的前面,一般情況下,第i(i大於等於1)個記錄進行插入操作時,R1、 R2,…,是排好序的有序數列,取出第i個元素,在序列中找到一個合適的位置並將她插入到該位置上即可。

        插入排序—希爾排序

        基本思想:算法先將要排序的一組數按某個增量d(n/2,n爲要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。我們來看下面的一張圖,如下所示:

        

        我們來看一個關於希爾排序的例子,如下圖所示:

        

        希爾排序具體的做法結合上述排序,我們可以很清楚的看出來,先取一個小於n的整數d1作爲第一個增量,把序列分爲d1個組,即將所有距離爲d1倍數序號的記錄放在同一個組中,在各組內進行直接插入排序,然後去第二個增量d2,d2小於d1,重複上述分組和排序工具,依次類推,直至所取的增量di=1,即所有記錄放在同一組進行直接插入排序爲止。

        交換排序—冒泡排序

        交換排序的基本思想是,比較兩個記錄鍵值的大小,如果這兩個記錄鍵值的大小出現逆序,則交換這兩個記錄,這樣將鍵值較小的記錄向序列前部移動,鍵值較大的記錄向序列後部移動。首先我們來看交換排序中的第一種排序—冒泡排序,首先將第一個記錄的鍵值和第二個鍵值進行比較,若爲逆序,即R[1].key大於R[2].key,則將這兩個記錄交換,然後繼續比較第二個和第三個記錄的鍵值,依此類推,直到完成第n-1個記錄和第n個記錄的鍵值比較交換爲止,上述過程稱爲第一趟起泡,其結果使鍵值最大的記錄移到了第n個位置上,然後再進行第二趟起泡,即對前n-1個記錄進行同樣的操作,其結果是次大鍵值的記錄安置在第n-1個位置上,重複上面的過程,當在一趟起泡過程中沒有進行記錄交換的操作時,整個排序過程終止,我們來看下面的一張圖:

        

        該方法的排序過程與氣泡從水中往上冒的情況很相似,所以,美其名曰:冒泡排序,從上圖我們可以很清楚的看出來,在排序的過程中,鍵值較小的記錄好比氣泡一樣向上漂浮,鍵值較大的記錄則向下沉。

        交換排序—快速排序

        快速排序是交互排序的一種,實質上是對冒泡排序的一種改進,快速排序的基本思想是,在n個記錄中取某一個記錄的鍵值爲標準,通常取第一個記錄鍵值爲基準,通過一趟排序將待排的記錄分爲小於或等於這個鍵值的兩個獨立的部分,這是一部分的記錄鍵值均比另一部分記錄的鍵值小,然後,對這兩部分記錄繼續分別進行快速排序,以達到整個序列有序,我們來看下面的一張圖:

        


        歸併排序

        所謂的歸併,是將兩個或兩個以上的有序文件合併成爲一個新的有序文件,歸併排序是把一個有n個記錄的無序文件看成是由n個長度爲1的有序子文件組成的文件,然後進行兩兩歸併,如此重複,直至最後形成包含n個歸併,得到n/2個長度爲2或者1的有序文件,再兩兩歸併,如此重複,直至最後形成包含n個記錄的有序文件位置,這種反覆將兩個有序文件歸併成一個有序文件的排序方法稱爲二路歸併排序。二路歸併排序的核心操作是將一堆數組中前後相鄰的兩個有序序列歸併爲一個有序序列,如下圖所示:

         


        基數排序

        基數排序(radix sort)屬於“分配式排序”(distribution sort),又稱“桶子法”(bucket sort)或bin sort,顧名思義,它是透過鍵值的部份資訊,將要排序的元素分配至某些“桶”中,藉以達到排序的作用,基數排序法是屬於穩定性的排序,其時間複雜度爲O (nlog(r)m),其中r爲所採取的基數,而m爲堆數,在某些時候,基數排序法的效率高於其它的穩定性排序法。我們來看下面的一個例子:

         

         8種排序的分類,穩定性,時間複雜度和空間複雜度總結如下所示:

         

         小編寄語:該博客,小編簡單的介紹了八種排序方法,分別詳細的介紹了每種排序到底是如何排序的,以及在博文的結尾,把各種算法的時間複雜度以及空間複雜度整理成了一張表格,希望可以幫助到有需要的小夥伴。排序是計算機內經常進行的一種操作,其目的是將一組“無序”的記錄序列調整爲“有序”的記錄序列。分內部排序和外部排序。若整個排序過程不需要訪問外存便能完成,則稱此類排序問題爲內部排序。反之,若參加排序的記錄數量很大,整個序列的排序過程不可能在內存中完成,則稱此類排序問題爲外部排序。內部排序的過程是一個逐步擴大記錄的有序序列長度的過程。

版權聲明:本文爲博主原創文章,未經博主

        </div>
            </div>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章