C++中七大排序算法

这里的七大指的是快速排序、堆排序、归并排序、希尔排序、选择排序、插入排序和冒泡排序,由于桶排序应用场景有限,这里就不写了。先对比一下这几种排序的效率:

C++中七大排序算法_第1张图片

观察表发现一个有趣的现象:对于堆排序和归并排序,他们的最好、最坏和平均的时间复杂度都是O(nlogn),也就是说数据的初始化顺序对这两种算法是没有影响的。先来一个直观的比较(500000条数据)

C++中七大排序算法_第2张图片

直观来看,快速排序、堆排序和归并排序的时间在一个数量级上,接着是希尔排序,最后是插入排序、选择排序和冒泡排序。至于排序原理我就不再说了,直接贴代码。

[cpp]  view plain copy
  1. //快速排序  
  2. int Paration(int a[], int low, int high)  
  3. {  
  4.     int key = a[low];  
  5.     while ( low < high )  
  6.     {  
  7.         while (low < high && a[high] >= key ) high--;  
  8.         a[low] = a[high];  
  9.   
  10.         while (low < high && a[low] <= key ) low++;  
  11.         a[high] = a[low];         
  12.     }  
  13.     a[low] = key;  
  14.     return low;  
  15. }  
  16. void QuickSort(int a[], int low, int high)  
  17. {  
  18.     if ( low < high )  
  19.     {  
  20.         int index = Paration(a, low, high);  
  21.         QuickSort(a, low, index - 1);  
  22.         QuickSort(a, index + 1, high);  
  23.     }  
  24. }  
调用:QuickSort(a, 0, N - 1);

[cpp]  view plain copy
  1. //堆排序  
  2. void HeapAdjust(int a[], int n, int k)  
  3. {  
  4.     int l = 2 * k + 1;  
  5.     int r = 2 * k + 2;  
  6.   
  7.     if ( l >= n && r >= n ) return;  
  8.   
  9.     int key = a[k];  
  10.     int left = 0x80000000;  
  11.     int right = 0x80000000;  
  12.       
  13.     if ( l < n ) left  = a[l];  
  14.     if ( r < n ) right = a[r];  
  15.     if ( key >= left && key >= right ) return;  
  16.   
  17.     if ( left > right )  
  18.     {  
  19.         a[k] = a[l];  
  20.         a[l] = key;  
  21.         HeapAdjust(a, n, l );  
  22.     }  
  23.     else  
  24.     {  
  25.         a[k] = a[r];  
  26.         a[r] = key;  
  27.         HeapAdjust(a, n, r);  
  28.     }  
  29. }  
  30.   
  31. void HeapSort(int a[], int n)  
  32. {  
  33.     for ( int i = ( n - 1 ) / 2; i >= 0; --i )  
  34.     {  
  35.         HeapAdjust(a, n, i);  
  36.     }  
  37.     while ( n )  
  38.     {  
  39.         int t = a[0];  
  40.         a[0] = a[n-1];  
  41.         a[n-1] = t;  
  42.         n -= 1;  
  43.         HeapAdjust(a, n, 0);  
  44.     }  
  45. }  
调用:HeapSort(a, N);

[cpp]  view plain copy
  1. //归并排序  
  2. void Merage(int a[], int low, int mid, int high, int tmp[])  
  3. {  
  4.     int len1 = mid - low + 1;  
  5.     int len2 = high - mid;  
  6.     memcpy(tmp, a + low, len1 * sizeof(int));  
  7.     memcpy(tmp + len1, a + mid + 1, len2 * sizeof(int));  
  8.       
  9.     int index = low;  
  10.     int i = 0;  
  11.     int j = len1;  
  12.     while ( i < len1 && j < len1 + len2 )  
  13.     {  
  14.         if (tmp[i] < tmp[j])  
  15.         {  
  16.             a[index++] = tmp[i++];  
  17.         }  
  18.         else  
  19.         {  
  20.             a[index++] = tmp[j++];  
  21.         }  
  22.     }  
  23.     while ( i < len1 )        a[index++] = tmp[i++];  
  24.     while ( j < len1 + len2 ) a[index++] = tmp[j++];  
  25. }  
  26.   
  27. void MergeSort(int a[], int low, int high)  
  28. {  
  29.     static int *tmp = new int[high];  
  30.     if ( low < high )  
  31.     {  
  32.         int mid = (low + high) / 2;  
  33.         MergeSort(a, low, mid);  
  34.         MergeSort(a, mid + 1, high);  
  35.         Merage(a, low, mid, high, tmp);  
  36.     }  
  37. }  
调用:MergeSort(a, 0, N - 1);

[cpp]  view plain copy
  1. //希尔排序  
  2. void ShellSort(int a[], int n)  
  3. {  
  4.     int step[] = {37, 31, 23, 19, 17, 13, 11, 7, 3, 1}; //步长  
  5.     for ( int k = 0; k < 10; ++k )  
  6.     {  
  7.         for (int i = step[k]; i < n; ++i )  
  8.         {  
  9.             int t = a[i];  
  10.             int j = i - step[k];  
  11.             for ( ; j >= 0 && t < a[j]; j -= step[k] )  
  12.             {  
  13.                 a[j + step[k]] = a[j];  
  14.             }  
  15.             a[j + step[k]] = t;  
  16.         }  
  17.     }  
  18. }  
调用:ShellSort(a, N);

[cpp]  view plain copy
  1. //插入排序  
  2. void InsertSort(int a[], int n)  
  3. {  
  4.     for ( int i = 1; i < n; ++i )  
  5.     {  
  6.         int t = a[i];  
  7.         int j = i - 1;  
  8.         for ( ; j >= 0 && t < a[j]; --j )  
  9.         {  
  10.                 a[j + 1] = a[j];  
  11.         }  
  12.         a[j+1] = t;  
  13.     }  
  14. }  
调用:InsertSort(a, N);  有没有发现希尔排序和插入排序很像,其实希尔排序就是插入排序,只不过步长不是1。

[cpp]  view plain copy
  1. //选择排序  
  2. void SelectSort(int a[], int n)  
  3. {  
  4.     for ( int i = 0; i < n; ++i )  
  5.     {  
  6.         int min = a[i];  
  7.         int index = i;  
  8.         for ( int j = i + 1; j < n; ++j )  
  9.         {  
  10.             if (a[j] < min )  
  11.             {  
  12.                 index = j;  
  13.                 min = a[j];  
  14.             }  
  15.         }  
  16.         a[index] = a[i];  
  17.         a[i] = min;  
  18.     }  
  19. }  
调用:SelectSort(a, N);

[cpp]  view plain copy
  1. //冒泡排序  
  2. void BubbleSort(int a[], int n)  
  3. {  
  4.     for (int i = 0; i < n; ++i)  
  5.     {  
  6.         for ( int j = 0; j < n - i - 1; ++j)  
  7.         {  
  8.             if ( a[j] > a[j+1] )  
  9.             {  
  10.                 int t = a[j];  
  11.                 a[j] = a[j+1];  
  12.                 a[j+1] = t;  
  13.             }  
  14.         }  
  15.     }  
  16. }  
调用:BubbleSort(a, N);

有没有发现,代码越简单的效率越低。需要注意的是在上面的写法中,调用快速排序和归并排序时,传入的参数数最后一个元素的下标,而不是数组的大小,就是说N - 1。

你可能感兴趣的:(归并排序,快速排序,插入排序,希尔排序,C语言)