1. 程式人生 > >排序演算法---希爾排序

排序演算法---希爾排序

參考網址:http://www.cnblogs.com/eniac12/p/5329396.html#s6
希爾排序,也叫遞減增量排序,是插入排序的一種更高效的改進版本。希爾排序是不穩定的排序演算法。
希爾排序是基於插入排序的以下兩點性質而提出改進方法的:
插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率
但插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位
希爾排序通過將比較的全部元素分為幾個區域來提升插入排序的效能。這樣可以讓一個元素可以一次性地朝最終位置前進一大步。然後演算法再取越來越小的步長進行排序,演算法的最後一步就是普通的插入排序,但是到了這步,需排序的資料幾乎是已排好的了(此時插入排序較快)。
假設有一個很小的資料在一個已按升序排好序的陣列的末端。如果用複雜度為O(n^2)的排序(氣泡排序或直接插入排序),可能會進行n次的比較和交換才能將該資料移至正確位置。而希爾排序會用較大的步長移動資料,所以小資料只需進行少數比較和交換即可到正確位置。

#include<iostream>
using namespace std;
// 分類 -------------- 內部比較排序
// 資料結構 ---------- 陣列
// 最差時間複雜度 ---- 根據步長序列的不同而不同。已知最好的為O(n(logn)^2)
// 最優時間複雜度 ---- O(n)
// 平均時間複雜度 ---- 根據步長序列的不同而不同。
// 所需輔助空間 ------ O(1)
// 穩定性 ------------ 不穩定
void ShellSort(int arr[], int n)
{
	int gap = 0;
	while (gap <= n)   // 生成初始增量
	{
		gap = gap * 3 + 1;
	}
	while (gap >= 1)
	{
		for (int i = gap; i < n; i++)
		{
			int j = i - gap;
			int get = arr[i];
			while (j >= 0 && arr[j]>get)
			{
				arr[j + gap] = arr[j];
				j = j - gap;
			}
			arr[j + gap] = get;
		}
		gap = (gap - 1) / 3;    // 遞減增量
	}
}

int main()
{
	int arr[] = { 6, 4, 8, 2, 5, 3, 1, 9, 5, 0 };
	int len = sizeof(arr) / sizeof(int);
	ShellSort(arr, len);
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << endl;
	}
	return 0;
}