排序演算法 希爾排序

2021-10-04 19:07:42 字數 2495 閱讀 7854

希爾排序(shell』s sort)是插入排序的一種,又稱為「縮小增量排序」(diminishing increment sort),是直接插入排序演算法的一種更高效的改進版本。

在介紹希爾排序之前,我們首先介紹直接插入排序演算法:

直接插入排序基本思想是每一步將乙個待排序的元素,插入到前面已經排好序的有序序列中去,直到插完所有元素為止。

**實現如下:

void insert_sort(vector& v)

我們分步來解釋這個**:

(1)首先將序列中首部的兩個元素進行比較,若v[0] > v[1],並且序列按照公升序排,那麼通過swap函式交換v[0]和v[1]的值。

(2)通過第一步,我們搭建了乙個包含兩個元素的有序序列,它位於整個序列的首部。接下來我們繼續拿第三個元素,即v[2]來和有序序列中的元素比較,首先v[2]和v[1]比較,倘若v[2] < v[1],那麼交換兩者順序,並且繼續將其和v[0]比較;倘若v[2] > v[1],則不需要再比較和交換元素。現在有序序列擴充為前三個元素。

(3)通過迴圈,每次拿入乙個新的元素與有序序列中的元素比較,找到合適的位置插入,直至所有元素都插入有序序列,此時演算法結束。

通過上述步驟,我們可以認識到:

直接插入排序更適合於規模較小或基本有序的序列,在最好的情況下,需要比較n - 1次,無需交換元素,時間複雜度為o(n);在最壞情況下,時間複雜度為o(n2)。

但實際上規模較小或基本有序的序列並不常見,為了改進直接插入排序,使得它對於中等規模或無序的序列也有較高效率,我們接下來引入希爾排序的概念。

先取乙個小於序列長度n的整數d1作為第乙個增量,把序列的全部元素分組。所有彼此之間距離為d1的元素分在同一組中(邏輯上分組,實際元素還在原序列中)。然後在各組內進行直接插入排序;然後,取第二個增量d2

< d1 重複上述的分組和排序,直至所取的增量dt =0(終止條件),說明序列中所有元素都已經排序完成。

下面通過例項來解釋shell排序的過程:

vectorv = ;
一般初次取增量為序列長度的一半,所以我們將增量設為 d1 = v.size() / 2 = 5;

那麼我們將原序列分為五個子串行:v[0]和v[5]、v[1]和v[6]、……、v[4]和v[9]; 然後在每個子串行進行直接插入排序,結束後序列如下:

vectorv = ;
然後我們增量取d2 = 5 / 2 = 2(整數型別向下取整),繼續分組,在每個分組中進行直接插入排序。

vectorv = ;
如果說第一次分組排序效果不明顯,現在隨著增量變小,我們可以明顯發現分序列的部分有序狀態正在逐漸影響主序列的有序性,原本亂序的主序列在經歷了兩次分組排序後,正朝著基本有序的方向演變,這就引出了希爾排序高效的原因:當起初增量較大的時候,直接插入排序在每個分組中所作用的資料量比較小,插入的效率比較高;而後面隨著增量縮小,序列往基本有序的方向演變,在這樣的序列上進行直接插入排序效率也很高。可以說希爾排序是完全利用了直接插入排序的優勢,策略性地處理主序列,使得排序效率大大增加。

最後一次,我們取增量d3 = 1,整個序列被分為一組,且整個序列已經接近有序了:

vectorv = ;
希爾排序的程式也分為兩個功能性函式:insert_sort和shell_sort

void insert_sort(vector& v, int begin, int delta)

可以看出用於shell』s sort中的insert_sort與一般情況下的insert_sort只有增量方面的不同而已,當delta == 1的時候,shell』s sort中的insert_sort 和 一般情況下的 insert_sort相同。

void shell_sort(vector& v)

希爾排序不需要大量的輔助空間,所以空間複雜度為o(1);至於希爾排序的時間複雜度的分析是乙個複雜的問題,因為希爾排序的時間複雜度是根據增量序列的選擇來決定的,所以用不同的序列會導致不同的時間複雜度,而什麼序列會導致最好的時間複雜度至今仍是尚未解決的難題。目前已知使用希爾增量(本文所使用的)時希爾排序的最壞情形執行時間為o(n2),使用hibbard所提出的增量序列時間複雜度最壞情況下為o(n3/2), sedgewick提出的幾種增量序列,其最壞情況下時間複雜度為o(n1.3)。

一般來說希爾排序的平均時間複雜度和最壞情況下的時間複雜度差不多(與快速排序不同,快速排序最壞情況下時間複雜度與平均情況下相差很大),希爾排序時間複雜度的下界是o(nlog2n),但一般來說希爾排序沒有快速排序演算法快,比o(n2)的演算法表現要好。希爾排序更適合於中等規模的序列,而不適合於規模非常大的資料排序。

由於多次直接插入排序,我們知道直接插入排序是穩定的,不會改變相同元素的相對順序,但在不同的插入排序過程中,相同的元素可能在各自的插入排序中移動,最後其穩定性就會被打亂,所以shell排序是不穩定的。

排序演算法 希爾排序

如果乙個排序演算法,每次只把諸專案移動乙個位置,則它的平均執行時間至少要和n2成比例.因為在這個排序演算法執行的過程當中,每個記錄平均都必須遍歷n 3個位置,因此如果要對直接插入排序進行有效的,實質性的改進的話,就要有一種演算法,它可以使記錄做長距離的跳躍,而不是一步一步的挪動.希爾排序也是一種插入...

排序演算法 希爾排序

摘要 排序演算法有很多,最簡單的有氣泡排序和插入排序,這兩種方法都具有o n 2 的時間界.我們想要討論的是具有更好的時間界的排序演算法,比如希爾排序.1 希爾排序的思路是通過比較一定間距的元素來進行排序,最後再對所有相鄰元素進行一次插入排序.2 希爾排序最重要的引數是增量序列 h1,h2,ht 只...

排序演算法 希爾排序

希爾排序,也稱遞減增量排序演算法,是插入排序的一種更高效的改進版本。希爾排序是非穩定排序演算法。希爾排序通過將比較的全部元素分為幾個區域來提公升插入排序的效能。這樣可以讓乙個元素可以一次性地朝最終位置前進一大步。然後演算法再取越來越小的步長進行排序,演算法的最後一步就是普通的插入排序,但是到了這步,...