比较类排序
交换排序
冒泡排序
void bubble_sort(int arr[], int low, int high) {
int len = high-low+1;
for (int i = 0; i < len-1; ++i) {
for (int j = 0; j < len-1-i; ++j) {
if (arr[j+low] > arr[j+1+low]) {
swap(arr[j+low],arr[j+1+low]);
}
}
}
}
快速排序
void quick_sort(int arr[], int low, int high) {
if (low >= high) return;
int i = low, j = high, tmp = arr[low];
while (i < j) {
while (i < j && arr[j] >= tmp) j--;
arr[i] = arr[j];
while (i < j && arr[i] <= tmp) i++;
arr[j] = arr[i];
}
arr[i] = tmp;
quick_sort(arr, low, i-1);
quick_sort(arr, i+1, high);
}
插入排序
简单插入排序
void insert_sort(int arr[], int low, int high) {
for (int i = low+1; i <= high; ++i) {
int tmp = arr[i], j;
for (j = i-1; j >= low; --j) {
if (arr[j] <= tmp) break;
arr[j+1] = arr[j];
}
arr[j+1] = tmp;
}
}
希尔排序
void shell_sort(int arr[], int low, int high) {
int len = high-low+1;
for (int t = len/2; t > 0; t /= 2) {
for (int i = low+t; i <= high; ++i) {
int tmp = arr[i], j;
for (j = i-t; j >= low; j -= t) {
if (arr[j] <= tmp) break;
arr[j+t] = arr[j];
}
arr[j+t] = tmp;
}
}
}
选择排序
简单选择排序
void select_sort(int arr[], int low, int high) {
for (int i = low; i <= high-1; ++i) {
int min_index = i;
for (int j = i+1; j <= high; ++j) {
if (arr[min_index] > arr[j]) {
min_index = j;
}
}
swap(arr[min_index],arr[i]);
}
}
堆排序
void heapify(int arr[], int root, int low, int len) {
int left = 2*root+1;
int right = 2*root+2;
int max_index = root;
if (left < len && arr[left+low] > arr[max_index+low]) max_index = left;
if (right < len && arr[right+low] > arr[max_index+low]) max_index = right;
// 如果需要调整
if (max_index != root) {
// 交换父节点和子节点的值
swap(arr[root+low],arr[max_index+low]);
// 判断子节点是否需要交换
heapify(arr, max_index, low, len);
}
}
void build_max_heap(int arr[], int low, int len) {
// 从最后一个非叶节点开始向前遍历,调整成为大顶堆
for (int i = len/2-1; i >= 0; --i) {
heapify(arr, i, low, len);
}
}
void heap_sort(int arr[], int low, int high) { // [low,high]
int len = high-low+1;
build_max_heap(arr, low, len);
for (int i = len-1; i > 0; --i) {
swap(arr[0+low],arr[i+low]);
len--;
heapify(arr, 0, low, len);
}
}
归并排序
void merge(int arr[], int tmp[], int low, int high) {
if (low >= high) return;
int mid = low + (high-low)/2;
merge(arr, tmp, low, mid);
merge(arr, tmp, mid+1, high);
int i = low, j = mid+1, k = low;
while (i <= mid && j <= high) {
tmp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];
}
while (i <= mid) tmp[k++] = arr[i++];
while (j <= high) tmp[k++] = arr[j++];
for (k = low; k <= high; ++k) arr[k] = tmp[k];
}
void merge_sort(int arr[], int low, int high) {
int tmp[high-low+1];
merge(arr, tmp, low, high);
}
非比较类排序
计数排序
void counting_sort(int arr[], int low, int high, int max_num) {
int tmp[max_num+1];
memset(tmp,0,sizeof(tmp));
for (int i = low; i <= high; ++i) {
tmp[arr[i]]++;
}
int j = low;
for (int i = 0; i <= max_num; ++i) {
while (tmp[i]--) arr[j++] = i;
}
}
桶排序
void bucket_sort(int arr[], int low, int high) {
// 找出最大最小值
int max_num = arr[low];
int min_num = arr[low];
for (int i = low+1; i <= high; ++i) {
max_num = max(max_num, arr[i]);
min_num = min(min_num, arr[i]);
}
// 计算桶的数量
int len = high-low+1;
int bucket_num = (max_num-min_num)/len + 1;
vector<int> bucket_arr[bucket_num];
// 将每个元素放入桶
for (int i = low; i <= high; ++i) {
int num = (arr[i]-min_num) / len;
bucket_arr[num].push_back(arr[i]);
}
// 对每个桶进行排序,可以使用快排
for (int i = 0; i < bucket_num; ++i) {
sort(bucket_arr[i].begin(),bucket_arr[i].end());
}
// 将桶中的元素赋值到原序列
int k = low;
for (int i = 0; i < bucket_num; ++i) {
for (int j = 0; j < bucket_arr[i].size(); ++j) {
arr[k++] = bucket_arr[i][j];
}
}
}
基数排序
void radix_sort(int arr[], int low, int high, int max_digit) {
int mod = 10;
int dev = 1;
for (int i = 0; i < max_digit; ++i, dev *= 10, mod *= 10) {
vector<int> counter[10];
for (int j = low; j <= high; ++j) {
int bucket = (arr[j]%mod)/dev;
counter[bucket].push_back(arr[j]);
}
int pos = low;
for (int j = 0; j < 10; ++j) {
for (int k = 0; k < counter[j].size(); ++k) {
arr[pos++] = counter[j][k];
}
}
}
}
快速排序优化
#include <bits/stdc++.h>
using namespace std;
int arr[1000005];
// 插入排序
void insert_sort(int arr[], int low, int high) {
for (int i = low+1; i <= high; ++i) {
int tmp = arr[i], j;
for (j = i-1; j >= low; --j) {
if (arr[j] <= tmp) break;
arr[j+1] = arr[j];
}
arr[j+1] = tmp;
}
}
// 快速排序
void quick_sort(int arr[], int low, int high) {
if (low >= high) return;
// 序列长度少时使用插入排序
if (high - low < 20) {
insert_sort(arr,low,high);
return;
}
// 三数取中,并将中间值放在最左边
int mid = low + (high-low)/2;
if (arr[mid] > arr[high]) swap(arr[mid],arr[high]);
if (arr[low] > arr[high]) swap(arr[low],arr[high]);
if (arr[mid] > arr[low]) swap(arr[low],arr[mid]);
// 快排
int i = low, j = high, tmp = arr[low];
while (i < j) {
while (i < j && arr[j] >= tmp) j--;
arr[i] = arr[j];
while (i < j && arr[i] <= tmp) i++;
arr[j] = arr[i];
}
arr[i] = tmp;
quick_sort(arr, low, i-1);
quick_sort(arr, i+1, high);
}
int main() {
for (int i = 0; i < 1000000; ++i) arr[i] = 99999999-i;
// srand(1); // 设置随机种子
// random_shuffle(arr,arr+1000000); // 打乱序列
clock_t startTime, endTime;
startTime = clock();
quick_sort(arr, 0, 999999);
endTime = clock();
cout << "quick_sort run time: " << (endTime-startTime)/1000.0 << endl;
return 0;
}