几个排序算法及其性能比较

来源:互联网 发布:红楼梦87版柳湘莲 知乎 编辑:程序博客网 时间:2024/06/04 18:14

#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排序的稳定性最好?

 
原创粉丝点击