1、直接插入排序
比較次數最好n-1,最壞n(n-1)/2,平均比較複雜度爲O(n^2),平均移動複雜度也爲O(n^2),穩定的排序方法,在大部分元素有序的情況下,表現優良。不適合數據量較大的排序,小於千的數量級,是不錯選擇(文末有測試數據)。STL的sort算法和stdlib的qsort算法中,都將插入排序作爲快速排序的補充,用於少量元素的排序(通常爲8個或以下)
void insert_sort(int a[], int len)
{
int i, j, temp;
for(i = 1; i < len; i++)
{
temp = a[i];
for( j = i -1; j >= 0 && a[j] >= temp; a[j + 1] = a[j], j--);
a[j + 1] = temp;
}
}
可在上述程序中去掉地7行中a[j] >= temp表達式中的等號,優化相等情況的性能
2.二分插入排序
也是穩定的排序方法,和直接插入比較,減少了比較次數,數據規模大時,比直接插入稍微好些,但改觀不大,平均移動複雜度也爲O(n^2)
int binary_search(int elm, int start_pos, int end_pos)
{
if (start_pos == end_pos)
return start_pos;
else
{
int tmp_pos = (start_pos + end_pos) / 2;
if (tmp_pos == start_pos)
return start_pos;
if (elm > a[tmp_pos])
binary_search(elm, tmp_pos, end_pos);
else if (elm < a[tmp_pos])
binary_search(elm, start_pos, tmp_pos);
else
return tmp_pos;
}
}
void isort_binary(int a[], int len)
{
int i, j, temp, pos;
for (i = 1; i < len ; i++)
{
temp = a[i];
pos = binary_search(temp, 0, i - 1);
for (j = i - 1; j > pos; a[j + 1] = a[j], j--);
a[pos+1] = temp;
}
}
3. 希爾排序 wiki
是插入排序的一種更高效的改進版本,非穩定排序算法,把直接插入每次移動的一次改爲一定的步長,並按照一定規律遞減,最終爲1.
舉個例子,以步長20開始,折半遞減
void shell_sort(int a[], int len)//#define INITSTEP 20
{
int step, i, j, temp;
for (step = INITSTEP; step >= 1; step /= 2)
{
for (i = 1; i < len; i++)
{
temp = a[i];
for (j = i - step; j >= 0 && a[j] > temp; a[j + step] = a[j], j -= step);
a[j + step] = temp;
}
}
}
希爾排序的時間複雜度與增量序列的選取有關,比較在希爾排序中是最主要的操作,而不是交換好的增量序列的共同特徵:
① 最後一個增量必須爲1;
② 應該儘量避免序列中的值(尤其是相鄰的值)互爲倍數的情況。
參考一下維基百科裏的各種步長效率:
總的說來,它比O(N^2)複雜度的算法快得多,並且容易實現,此外,希爾算法在最壞的情況下和平均情況下執行效率相差不是很多
博主純手工肉測了一組數據,小做參考
測試程序和數據打包到這裏:http://download.csdn.net/detail/simon_uestc/6858561
可以看出希爾的效率着實喜人,再馬克一個測試截圖以做紀念