O(n^2)
双层n循环: 一次用于确定每个数字的位值,一层用于对所有元素确定位值。
-
选择排序:
每次遍历数组,选择出余下部分最小的值放到余下部分的头部。
for (int i = 0; i < arr.size(); i++) { int minT = i; for (int j = i; j < arr.length(); j++) { if (arr[minT] > arr[j]) minT = j; } swap(arr[i], arr[minT]); }
-
插入排序:
保证前面一部分数组有序,然后把后面无序数组中的元素插入到前面有序数组中,并保持前面的数组有序。
for (int i = 1; i < arr.size(); i++) { //多次使用swap,消耗时间较长 for (int j = i; j > 0 && (arr[j - 1] > arr[j]); j--) swap(arr[j - 1], arr[j]); }
for (int i = 1; i < 9; i++) { int j = i; int target = arr[i]; //减少swap的次数,提高了运行效率 for (j; j > 0 && (target < arr[j - 1]); j--) { arr[j] = arr[j - 1]; } swap(arr[j], target); }
O(N*log N)
一层n,一层logn: logn层多为用递归的方式遍历数组,而确定数字位置仍需O(n)级别的遍历。
-
归并排序
递归划分,逐级合并。
//逐级合并 template<typename T> void __merge(T *arr, int l, int mid, int r) { T aux[r - l + 1]; for (int i = l; i <= r; i++) aux[i - l] = arr[i]; int i = l, j = mid + 1; for (int k = l; k <= r; k++) { if (i > mid) { arr[k] = aux[j - l]; j++; } else if (j > r) { arr[k] = aux[i - l]; } else if (aux[i - l] < aux[j - l]) { arr[k] = aux[i - l]; i++; } else { arr[k] = aux[j - l]; j++; } } } //递归划分 template<typename T> void __mergeSort(T arr[], int l, int r) { if (l >= r) return; int mid = (r - l) / 2 + l;//(l+r)/2的另一种写法,防止数据溢出 __mergeSort(arr, l, mid); __mergeSort(arr, mid + 1, r); __merge(arr, l, mid, r); } //外层调用 template<typename T> void mergeSort(T arr[], int n) { __mergeSort(arr, 0, n - 1); }
-
快速排序
template<typename T> void __partition(T arr[], int l, int r) { srand(time(NULL));// swap(arr[l], arr[rand() % (r - l + 1) + l]); T v = arr[l]; int j = l; for (int i = l + 1; i <= r; i++) { if (arr[i] < v) swap(arr[++j], arr[i]); } swap(arr[l],arr[j]); return j; } template<typename T> void __quickSort(T arr[], int l, int r) { if (l >= r) return; int p = __partition(arr, l, r); __quickSort(arr, l, p - 1); __quickSort(arr, p + 1, r); } template<typename T> void quickSort(T arr[], int n) { __quickSort(arr, 0, n - 1); }
-
堆排序
//ShiftUp 把新加入的元素移动到合适的位值 private: T *data; int count; void shiftUp(int k) { while (k > 1 && data[k] > data[k / 2]) { swap(data[k], data[k / 2]); k /= 2; } } public: template<typename T> void insert(T item) { data[count + 1] = item; count++; shiftUp(count); }
//shiftDown 从堆中取出最大的元素(最大堆中) private: T *data; int count; void shiftDown(int k) { while (2 * k <= count) { int j = 2 * k; if (j + 1 <= count && data[j + 1] > daya[j]) j += 1; //不用交换,稳定 if (data[k] >= data[j]) break; swap(data[j], data[k]); k = j; } } public: template<typename T> T extracMax() { assert(count > 0); T item = data[1]; swap(data[1], data[count--]); shiftDown(1); return item; }