實際上是基於插入排序的,在插入排序中相比較的是相鄰的兩個元素,
但是如果一個很小的數在數組的最右端,而他本應該是在最左端的,
這樣的話所有中間的元素都要向右移動一位,並且執行了N次。
希爾排序就是首先對大跨度的元素做比較並且進行移動,這樣的就相對有序了,
再在這個基礎上進行普通的插入排序,效率就會高很多。
效率:
快速排序>希爾排序>簡單排序
希爾排序在最壞的執行效率上和平均的執行效率上沒有差很多。
希爾排序(Shell Sort)也稱爲遞減增量排序,是插入排序的一種高速而穩定的改良版。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
# 插入排序在對幾乎已經排好序的數據操作時,效率高,即可以達到線性排序的效率
# 但插入排序一般來說是低效的,因爲插入排序每次只能將數據移動一位
對有n個元素可比較的資料,先取一個小於n的整數d₁作爲第一個增量,把文件的全部記錄分成d₁個組。
所有距離爲d₁的倍數的記錄放在同一個組中。先在各組內進行直接插入排序;然後,取第二個增量d₂<d₁
重複上述的分組和排序,直至所取的增量爲1,即所有記錄放在同一組中進行直接插入排序爲止。
該方法實質上是一種分組插入方法。
eg 7 3 5 8 9 1 2 4 6
增量increment : 9/2 = 4; 分組,每組4個元素 7358 9124 6
7358 9124 6
7158 9324 6
7128 9354 6
7124 9358 6
7124 6358 9
6124 7358 9
increment : 4/2 = 2; 分組,每組2個元素 61 24 73 58 9
21 64 73 58 9
21 63 74 58 9
21 63 54 78 9
21 53 64 78 9
increment : 2/2 = 1; 分組,每組1個元素 2 1 5 3 6 4 7 8 9
1 2 5 3 6 4 7 8 9
1 2 3 5 6 4 7 8 9
1 2 3 5 4 6 7 8 9
1 2 3 4 5 6 7 8 9over
#include <iostream>
using namespace std;
typedef int T;
void PrintArry(int a[], int n)
{
for (int i=0; i<n; i++)
cout<< a[i]<<" ";
cout<<endl;
}
void ShellSort(T a[], int n){
int i, j;
T temp;
int increment = n/2;
while (increment > 0)
{
for(i = increment; i<n; i++){
temp = a[i];
j = i;
while (j-increment>=0 && temp < a[j-increment])
{
a[j] = a[j-increment];
j -= increment;
}
a[j] = temp;
}
increment /= 2;
PrintArry(a, 9);
}
}
int main(){
int a[9] = {7,3,5,8,9,1,2,4,6};
ShellSort(a, 9);
//PrintArry(a, 9);
return 0;
}