//优化后voidSelectSort(int* arr, int n) {
int begin = 0, end = n - 1;
while (begin < end) {
int mini = begin, maxi = begin;
for (int i = begin + 1; i <= end; i++) {
if (arr[i] > arr[maxi]) {
maxi = i;
}
if (arr[i] < arr[mini]) {
mini = i;
}
}
if (begin == maxi) {
maxi = mini;
}
Swap(&arr[mini], &arr[begin]);
Swap(&arr[maxi], &arr[end]);
++begin;
--end;
}
}
int _QuickSort(int* arr, int left, int right) {
int hole = left;
int key = arr[hole];
while (left < right) {
while (left < right && arr[right] > key) {
--right;
}
arr[hole] = arr[right];
hole = right;
while (left < right && arr[left] < key) {
++left;
}
arr[hole] = arr[left];
hole = left;
}
arr[hole] = key;
return hole;
}
2.3.2.3 lomuto 前后指针(重要)
创建前后指针,从左往右找比基准值小的进行交换,使得小的都排在基准值的左边。
int _QuickSort(int* arr, int left, int right) {
int prev = left, cur = left + 1;
int key = left;
while (cur <= right) {
if (arr[cur] < arr[key] && ++prev != cur) {
Swap(&arr[cur], &arr[prev]);
}
++cur;
}
Swap(&arr[key], &arr[prev]);
return prev;
}
快速排序特性总结:
时间复杂度:O(nlogn)
空间复杂度:O(logn)
2.3.2.4 非递归版本(重要)
非递归版本的快速排序需要借助数据结构:栈
代码实现
voidQuickSortNonR(int* arr, int left, int right) {
ST st;
STInit(&st);
STPush(&st, right);
STPush(&st, left);
while (!STEmpty(&st)) {
int begin = STTop(&st);
STPop(&st);
int end = STTop(&st);
STPop(&st);
// 单趟int keyi = begin;
int prev = begin;
int cur = begin + 1;
while (cur <= end) {
if (arr[cur] < arr[keyi] && ++prev != cur)
Swap(&arr[prev], &arr[cur]);
++cur;
}
Swap(&arr[keyi], &arr[prev]);
keyi = prev;
// [begin, keyi-1] keyi [keyi+1, end]if (keyi + 1 < end) {
STPush(&st, end);
STPush(&st, keyi + 1);
}
if (begin < keyi - 1) {
STPush(&st, keyi - 1);
STPush(&st, begin);
}
}
STDestroy(&st);
}
2.4 归并排序(重要)
归并排序算法思想:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
归并递归排序核心步骤:
代码实现
void _MergeSort(int* arr, int left, int right, int* tmp) {
if (left >= right) {
return;
}
int mid = (right + left) / 2;
// [left,mid] [mid+1,right]
_MergeSort(arr, left, mid, tmp);
_MergeSort(arr, mid + 1, right, tmp);
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int index = begin1;
//合并两个有序数组为一个数组while (begin1 <= end1 && begin2 <= end2) {
if (arr[begin1] < arr[begin2]) {
tmp[index++] = arr[begin1++];
} else {
tmp[index++] = arr[begin2++];
}
}
while (begin1 <= end1) {
tmp[index++] = arr[begin1++];
}
while (begin2 <= end2) {
tmp[index++] = arr[begin2++];
}
for (int i = left; i <= right; i++) {
arr[i] = tmp[i];
}
}
voidMergeSort(int* arr, int n) {
int* tmp = (int*)malloc(sizeof(int) * n);
_MergeSort(arr, 0, n - 1, tmp);
free(tmp);
}
//Sort.h#pragma once#include<stdio.h>#include<memory.h>#include<stdlib.h>//插入排序//1)直接插入排序 <n^2voidInsertSort(int* arr, int n);
//2)希尔排序 n^1.3voidShellSort(int* arr, int n);
//选择排序//1)直接选择排序 n^2voidSelectSort(int* arr, int n);
//2)堆排序 nlognvoidHeapSort(int* arr, int n);
//交换排序//1)冒泡排序 n^2voidBubbleSort(int* arr, int n);
//2)快速排序 nlognvoidQuickSort(int* arr, int left, int right);
//3)非递归版本的快速排序voidQuickSortNonR(int* arr, int left, int right);
//归并排序 nlognvoidMergeSort(int* arr, int n);
//非比较排序voidCountSort(int* arr, int n);