10大排序算法
冒泡排序
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
void bubbleSort(std::vector<int> &v) {
int n = v.size();
if (n < 2) return;
// 增加一个标志位 判断是否发生比较
bool flag = false;
// 总的趟数 n个数只需要比较n-1趟
for (int i=n-1; i>0; --i) {
flag = false;
// 每一趟需要的次数为i次
for (int j=0; j<i; ++j) {
if (v[j] > v[j+1]) {
int t = v[j];
v[j] = v[j+1];
v[j+1] = t;
flag = true;
}
}
if (!flag) return;
}
}
int main() {
srand(time(NULL));
std::vector<int> v(10);
for (int i=0; i<10; ++i) {
v.push_back(rand());
}
printf("排序前:\n");
for(const auto&i: v) {
printf("%d ", i);
}
printf("\n");
printf("排序后:\n");
bubbleSort(v);
for (const auto&i: v) {
printf("%d ", i);
}
printf("\n");
return 0;
}
选择排序
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
void selectSort(std::vector<int>& v) {
if (v.size() < 2) return;
int minPos = 0;
for (int i=0; i<v.size()-1; ++i) {
minPos = i;
for (int j=i+1; j<v.size(); ++j) {
if (v[j] < v[minPos]) {
minPos = j;
}
}
if (minPos != i) {
int t = v[minPos];
v[minPos] = v[i];
v[i] = t;
}
}
}
void selectSort2(std::vector<int>& v) {
int l = 0, r = v.size()-1;
int minPos = 0, maxPos = 0;
while (l < r) {
minPos = maxPos = l;
for(int i=l; i<=r; ++i) {
if (v[i] < v[minPos]) minPos = i;
if (v[i] > v[maxPos]) maxPos = i;
}
if (minPos != l) {
int t = v[minPos];
v[minPos] = v[l];
v[l] = t;
}
// 若最左侧是最大数时,此时最大数位置已被换走
if (maxPos == l) maxPos = minPos;
if (maxPos != r) {
int t = v[maxPos];
v[maxPos] = v[r];
v[r] = t;
}
++l;
--r;
}
}
int main() {
srand(time(nullptr));
std::vector<int> v;
for (int i=0; i<10; ++i) {
v.push_back(rand() % 100);
}
printf("排序前\n");
for (const auto& i:v) {
printf("%d ", i);
}
printf("\n");
// selectSort(v);
selectSort2(v); // 优化后, 一次确定两个数
printf("排序后\n");
for (const auto&i: v) {
printf("%d ", i);
}
return 0;
}
插入排序
#include <cstdio>
#include <ctime>
#include <cstdlib>
void insertSort(int arr[], int n) {
int i=0, j=0;
for (i=1; i<n; ++i) {
int tmp = arr[i]; //记录待插入值
for (j=i-1; (j>=0)&&(arr[j]>tmp); --j) {
arr[j+1] = arr[j]; //从后往前 覆盖查找
}
arr[j+1] = tmp;
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
int n = sizeof(arr) / sizeof(int);
for (int i=0; i<n; ++i) {
arr[i] = rand() % 100;
}
printf("before:\n");
for (int i=0; i<n; ++i){
printf("%d ", arr[i]);
}
printf("\n");
insertSort(arr, n);
printf("after:\n");
for (int i=0; i<n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
希尔排序
#include <cstdio>
#include <ctime>
#include <cstdlib>
void shellSort(int arr[], int n, int step) {
int i=0, j=0;
// 插入排序即可
for (i=step; i<n; ++i) {
int tmp = arr[i];
for (j=i-step; j>=0&&arr[j]>tmp; j-=step) {
arr[j+step] = arr[j];
}
arr[j+step] = tmp;
}
}
void shell(int arr[], int n) {
// shell step
for (int step=n/2; step>0; step/=2) {
shellSort(arr, n, step);
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
int n = sizeof(arr) / sizeof(int);
for (int i=0; i<n; ++i) {
arr[i] = rand() % 100;
}
printf("before:\n");
for (int i=0; i<n; ++i){
printf("%d ", arr[i]);
}
printf("\n");
shell(arr, n);
printf("after:\n");
for (int i=0; i<n; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
快速排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
int partition(int* arr, int low, int high) {
int pivot = arr[low];
int left = low, right = high;
while (left<right) {
while (left<right && arr[right]>=pivot) right--;
arr[left] = arr[right];
while (left<right && arr[left]<=pivot) left++;
arr[right] = arr[left];
}
arr[left] = pivot;
return left;
}
void quickSort(int* arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi+1);
quickSort(arr, pi+1, high);
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
memset(arr, 0, sizeof(arr));
int len = sizeof(arr) / sizeof(int);
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for(int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
quickSort(arr, 0, len-1);
printf("after: \n");
for (int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
归并排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
void merge(int* arr, int low, int mid, int high) {
int tmp[high-low+1], k = 0;
int i=low, j=mid+1;
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++];
}
memcpy(arr+low, tmp, sizeof(tmp));
}
void mergeSort(int* arr, int low, int high) {
if (low < high) {
int mid = low + (high-low) / 2;
mergeSort(arr, low, mid);
mergeSort(arr, mid+1, high);
merge(arr, low, mid, high);
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
memset(arr, 0, sizeof(arr));
int len = sizeof(arr) / sizeof(int);
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for(int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
mergeSort(arr, 0, len-1);
printf("after: \n");
for (int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
堆排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
void swap(int* a, int* b) {
int t = *a;
*a = *b;
*b = t;
}
void heapfy(int* arr, int i, int n) {
int father = i;
int son = 2*father+1;
while (son <= n) {
if (son+1<=n && arr[son+1]>arr[son]) son++;
if (arr[father] > arr[son]) return;
swap(&arr[son], &arr[father]);
father = son;
son = 2*father+1;
}
}
void heapSort(int* arr, int len) {
for (int i=(len-1)/2; i>=0; --i) heapfy(arr, i, len-1);
for (int i=len-1; i>0; --i) { // 下沉
swap(&arr[0], &arr[i]);
heapfy(arr, 0, i-1); // i-1代表每次排序好一个数
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
memset(arr, 0, sizeof(arr));
int len = sizeof(arr) / sizeof(int);
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for(int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
heapSort(arr, len);
printf("排序后\n");
for (int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
计数排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
int argMax(int* arr, int len) {
int maxValue = -1;
for (int i=0; i<len; ++i) {
maxValue = arr[i] > maxValue ? arr[i] : maxValue;
}
return maxValue;
}
void countSort(int* arr, int len) {
int maxValue = argMax(arr,len);
int tmp[maxValue+1];
memset(tmp, 0, sizeof(tmp));
for (int i=0; i<len; ++i) {
tmp[arr[i]]++;
}
for (int i=0, k=0; i<maxValue+1; ++i) {
while (tmp[i]--) {
arr[k++] = i;
}
}
}
int main() {
srand(time(NULL));
int arr[10] = {0};
memset(arr, 0, sizeof(arr));
int len = sizeof(arr) / sizeof(int);
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for(int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
countSort(arr, len);
printf("after: \n");
for (int i=0; i<len; ++i) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
桶排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
int partition(int* arr, int low, int high) {
int pivot = arr[low];
int left = low, right = high;
while (left < right) {
while (left<right && arr[right]>=pivot) right--;
arr[left] = arr[right];
while (left<right && arr[left]<=pivot) left++;
arr[right] = arr[left];
}
arr[left] = pivot;
return left;
}
void quickSort(int* arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi-1);
quickSort(arr, pi+1, high);
}
}
void bucketSort(int* arr, int len) {
int bucket[len][len];
int bucketSize[len];
memset(bucket, 0, sizeof(bucket));
memset(bucketSize, 0,sizeof(bucketSize));
for (int i=0; i<len; ++i) {
bucket[arr[i]/10][bucketSize[arr[i]/10]++] = arr[i];
}
// 对每个桶调用一次排序算法
for (int i=0; i<len; ++i) {
quickSort(bucket[i], 0, bucketSize[i]-1);
}
for(int i=0, k=0; i<len; ++i) {
for (int j=0; j<bucketSize[i]; ++j) {
arr[k++] = bucket[i][j];
}
}
}
int main() {
srand(time(NULL));
int arr[10];
int len = sizeof(arr) / sizeof(int);
memset(arr, 0, sizeof(arr));
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for (const auto&i: arr) {
printf("%d ", i);
}
printf("\n");
bucketSort(arr, len);
printf("after: \n");
for (const auto&i: arr) {
printf("%d ", i);
}
printf("\n");
return 0;
}
基数排序
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
void argMax(int* arr, int len, int& maxValue) {
for (int i=0; i<len; ++i) {
maxValue = arr[i] > maxValue ? arr[i] : maxValue;
}
}
void _radixSort(int* arr, int len, int exp) {
int result[len]; // 暂存临时结果
int bucket[10]; // 10个桶
memset(result, 0, sizeof(result));
memset(bucket, 0, sizeof(bucket));
for (int i=0; i<len; ++i) { // 记录每个桶记录末尾数的个数
bucket[(arr[i]/exp)%10]++;
}
for (int i=1; i<10; ++i) { // 精妙之处 累加刚好是len
bucket[i] += bucket[i-1];
}
for (int i=len-1; i>=0; --i) {
int iexp = (arr[i]/exp)%10;
result[bucket[iexp]-1] = arr[i]; // 刚好是该数字所在的下标
bucket[iexp]--;
}
memcpy(arr, result, sizeof(result)); // 每一轮的值拷过去
}
void radixSort(int* arr, int len) {
int maxValue = 0;
argMax(arr, len, maxValue);
for (int exp=1; maxValue/exp>0; exp*=10) {
_radixSort(arr, len, exp);
}
}
int main() {
srand(time(NULL));
int arr[10];
int len = sizeof(arr) / sizeof(int);
memset(arr, 0, sizeof(arr));
for (int i=0; i<len; ++i) {
arr[i] = rand() % 100;
}
printf("before: \n");
for (const auto&i: arr) {
printf("%d ", i);
}
printf("\n");
radixSort(arr, len);
printf("after: \n");
for (const auto&i: arr) {
printf("%d ", i);
}
printf("\n");
return 0;
}