#include <iostream>
#include <ctime>
using namespace std;
template <typename T>
void swap( T arr[], int i, int j )
{
T temp;
temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
template <typename T>
void selectionSort( T arr[], int n )
{
int i, j, index;
T minValue;
for( i = 0; i < n; i++ )
{
minValue = arr[i];
for( j = i + 1; j < n; j++ )
{
if( minValue > arr[j] )
{
minValue = arr[j];
index = j;
}
}
if( minValue != arr[i] )
{
swap( arr, i, index );
}
}
}
template <typename T>
void insertionSort( T arr[], int n )
{
int i, j;
T value;
for( i = 1; i < n; i++ )
{
value = arr[i];
j = i;
while( j > 0 && value < arr[j-1] )
{
arr[j] = arr[j-1];
--j;
}
arr[j] = value;
}
}
template <typename T>
void bubbleSort( T arr[], int n )
{
bool index = true;
int i;
while( index == true )
{
index = false;
for( i = 1; i < n; i++ )
{
if( arr[i] < arr[i-1] )
{
swap( arr, i, i-1 );
index = true;
}
}
--n;
}
}
template <typename T>
void exchangeSort( T arr[], int n )
{
int i, j;
for( i = 0; i < n-1; i++ )
{
for( j = i + 1; j < n; j++ )
{
if( arr[i] > arr[j] )
{
swap( arr, i, j );
}
}
}
}
//定步长的插入排序(shell排序调用)
template <typename T>
void insertionSort( T arr[], int beg, int end, int k )
{
int i = beg;
int j;
T value;
while( i < end )
{
j = i + k;
if( j >= end ) return;
value = arr[j];
while( j > 0 && j - k >= 0 && value < arr[j-k] )
{
arr[j] = arr[j-k];
j-=k;
}
arr[j] = value;
i += k;
}
}
template <typename T>
void shellSort( T arr[], int n )
{
int k, i, j;
for( k = 1; k <= n/9; k = 3 * k + 1 );
for( i = k; i >= 1; i-- )
{
for( j = 0; j < i; j++ )
{
insertionSort( arr, j, n, i );
}
}
}
//测试后,发现插入 排序的效果最好,选择排序其次,而shell排序的效果也并不是想像中的那么好。
测试结果如下(为长度为50000的整型数组排序结果)
time of selectionSort taken is: 5125
time of insertionSort taken is: 3890
time of bubbleSort taken is: 21625
time of exchangeSort taken is: 17375
time of shellSort taken is: 7734
同时,考虑到排序函数中再次调用函数的影响,在swap函数跟insertionSort(T arr[], int beg, int end, int k )加上inline,效果如下:
time of selectionSort taken is: 4859
time of insertionSort taken is: 3812
time of bubbleSort taken is: 21282
time of exchangeSort taken is: 17344
time of shellSort taken is: 7891
两者用的时间差不多,看来函数的调用对排序的结果影响不是很大。
如果开始就有序的情况下(最好情况),测试结果如下:
time of selectionSort taken is: 4609
time of insertionSort taken is: 0
time of bubbleSort taken is: 0
time of exchangeSort taken is: 5687
time of shellSort taken is: 6672
开始逆序的情况下(最坏情况):
time of selectionSort taken is: 5687
time of insertionSort taken is: 7469
time of bubbleSort taken is: 21250
time of exchangeSort taken is: 20469
time of shellSort taken is: 6671
另外,冒泡排序跟交换排序,由于涉及到更多的数组元素的交换,故花去了较多的时间。在最好情况下,插入排序跟冒泡排序的时间复杂度为O(1),而插入排序的逆序效果确实很差o(n^2).
疑问:为什么书上推崇的shell排序效果会这么差(shell排序的时间复杂度为O(n^1.5),而选择跟插入排序的时间复杂度都为O(n^2))。比较了最坏情况跟最好情况,难道是shell排序的稳定性最好?