下面直接上代码:
#include <iostream> #include <algorithm> #include <iterator> using namespace std; /* *********************************************** Insert Sort ************************************************ */ /* *********** 0(n2) ************* 主要思想: 逐个将无序区的元素插入到有序区,单个元素是有序的。 */ void DirectInsertSort(int arr[], int length) { int tmp; int index; for (int i = 1; i < length; ++i) { if (arr[i] < arr[i - 1]) { tmp = arr[i]; index = i; while (index > 0 && arr[index - 1] > tmp) { arr[index] = arr[index - 1]; --index; } arr[index] = tmp; } } } /* ******** nlog(n) < X < O(n2) ************ 主要思想: 改进的直接插入排序,依据一组距离向量来确定哪两个元素比较,进而排序。如一组向量为{5,3,1}; */ void ShellSort(int arr[], int length, int dk) { int tmp; int index; for (int i = 0; i < length - dk; ++i) { if (arr[i] > arr[i + dk]) { tmp = arr[i + dk]; index = i; while (index >= 0 && arr[index] > tmp) { arr[index + dk] = arr[index]; index -= dk; } arr[index + dk] = tmp; } } } /* ********************************************** Exchange Sort ************************************************ */ /* ********** X <= O(n2) *********** 主要思想: 这个一个改进的冒泡排序,原始需要O(n2)时间复杂度,原因是原始的排序不是基于相邻元素的比较,所以没一趟仅知道有序区增加一个元素,其它区域的信息依然不知。 以下基于相邻元素的比较,可以确定更多有序区的范围,从而减少趟数,减少时间开销。 */ void AdvancedBubleSort(int arr[], int length) { int tmp = 0; int index = 0; for (int i = length - 1; i > 0; --i) { for (int j = 0; j < i; ++j) { if (arr[j] > arr[j + 1]) { index = j + 1; tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; } } i = index; index = 0; } } /* *************O(nlogn) < X < O(n2)***************** 主要思想: 类似二分查找,每次算法都希望将无序数组均分为两个大概相等的子数组,以此递归。 但有可能不理想,会造成和冒泡一样的开销(发生在:每次取到的哨兵元素都是边缘元素)。 */ int SubFastSort(int arr[], int low, int high) { int middle = arr[low]; while (low < high) { while (low < high && arr[high] > middle) high--; if (low == high) break; arr[low++] = arr[high]; while (low < high && arr[low] < middle) low++; if (low == high) break; arr[high--] = arr[low]; } arr[low] = middle; return low; } void FastSort(int arr[], int low, int high) { if (low >= high) return; int middle = SubFastSort(arr, low, high); FastSort(arr, low, middle-1); FastSort(arr, middle+1, high); } /* ********************************************** Merging Sort *************************************************** */ /* **************O(nlogn)************** 主要思想: 每次将数组一分为二递归下去,知道子数组元素个数为1,则有序了。 回调过程进行合并。 */ void MergeArray(int s[], int t[], int low, int middle, int high) { int t_index = low; int s_low = low; int s_middle = middle + 1; for ( ; s_low <= middle && s_middle <= high ; ) { if (s[s_low] < s[s_middle]) t[t_index++] = s[s_low++]; else t[t_index++] = s[s_middle++]; } while (s_low <= middle) t[t_index++] = s[s_low++]; while (s_middle <= high) t[t_index++] = s[s_middle++]; } void SubMergingSort(int s[], int t[], int i, int low, int high) { if (low == high) { if (1 == i%2) t[low] = s[low]; } else { int middle = ((high - low) >> 2) + low; //(low + high)/2; SubMergingSort(s, t, i+1, low, middle); SubMergingSort(s, t, i+1, middle+1, high); if (1 == i%2) MergeArray(s, t, low, middle, high); else MergeArray(t, s, low, middle, high); } } void MergingSort(int arr[], int length) { int *p = nullptr; p = (int *)malloc(sizeof(int)*length); if (p) { SubMergingSort(arr, p, 0, 0, length-1); free(p); } } /* ************************************************ Heap Sort ******************************************************** */ /* *************O(n2)***************** 主要思想: 找到要找的元素才进行交换,减少了交换的次数。 */ void SimpleSelectSort(int arr[], int length) { int min; for (int i = 0; i < length; ++i) { min = i; for (int j = i+1; j < length; ++j) { if (arr[i] > arr[j]) { min = j; } } if (min != i) { arr[min] = arr[min] ^ arr[i]; arr[i] = arr[min] ^ arr[i]; arr[min] = arr[min] ^ arr[i]; } } } /* ************O(nlogn)*************** 主要思想: 第一步: 利用数组索引,构建大堆项(排序结果是升序)或者小堆项(排序结果是降序)。 第二步: 交换头尾元素,数组长度变量减1,再构建成大/小堆项,再回到第一步 */ void ShiftDown(int arr[], int length, int pos) { int left, right; while (pos <= length/2-1) { left = pos*2+1; right = pos*2+2; if (right < length) { if (arr[left] < arr[right]) left = right; } if (arr[left] > arr[pos]) { arr[left] = arr[left] ^ arr[pos]; arr[pos] = arr[left] ^ arr[pos]; arr[left] = arr[left] ^ arr[pos]; pos = left; } else break; } } void MakeBigHeap(int arr[], int length) { int left; int right; for (int i = length/2 - 1; i >= 0; --i) { ShiftDown(arr, length, i); } } void HeapSort(int arr[], int length) { if (length <= 1) return ; MakeBigHeap(arr, length); int index = length-1; int left, right; while (index > 0) { swap(arr[0], arr[index--]); ShiftDown(arr, index+1, 0); // 保持大堆性质 } } int main(int argc, char *argv[]) { int arr[] = {9,5,6,4,8,7,3,1,2,0}; DirectInsertSort(arr, 10); int dk[] = {5,3,1}; int arr1[] = {9,5,6,4,8,7,3,1,2,0}; for (int i = 0; i < sizeof(dk)/sizeof(int); ++i) { ShellSort(arr1, 10, dk[i]); } int arr2[] = {9,5,6,4,8,7,3,1,2,0}; AdvancedBubleSort(arr2, 10); int arr3[] = {1,2,8,3,4,5,7,6,9,0}; MergingSort(arr3, 10); int arr4[] = {1,2,8,3,4,5,7,6,9,0}; FastSort(arr4, 0, 9); int arr5[] = {1,2,8,3,4,5,7,6,9,0}; SimpleSelectSort(arr5, 10); int arr6[] = {1,2,8,3,4,5,7,6,9,0}; HeapSort(arr6, 10); ostream_iterator<int> os_iter(cout, " "); copy(begin(arr), end(arr), os_iter); endl(cout); copy(begin(arr1), end(arr1), os_iter); endl(cout); copy(begin(arr2), end(arr2), os_iter); endl(cout); copy(begin(arr3), end(arr3), os_iter); endl(cout); copy(begin(arr4), end(arr4), os_iter); endl(cout); copy(begin(arr5), end(arr5), os_iter); endl(cout); copy(begin(arr6), end(arr6), os_iter); endl(cout); return 0; }