1. 选择排序
复杂度
每次选择第i小的数,与下标为i的数交换。
void selection(){
for(int i = 0; i < n; i++){
int minnum = i;
for(int j = i + 1; j < n; j++){
if(a[j] <= a[minnum]) minnum = j;
}
swap(a[minnum], a[i]);
}
}
2. 插入排序
复杂度
每次在0~i-1的有序子序列中寻找元素a[i]的位置,并移出空位 。
void insert(){
for(int i = 1; i < n; i++){
int rightnum = i;
int num = a[i];
for(int j = 0; j < i; j++){
if(a[i] <= a[j]){
rightnum = j;
break;
}
}
for(int j = i; j > rightnum; j--) a[j] = a[j - 1];
a[rightnum] = num;
}
}
3. 冒泡排序
复杂度
每次交换相邻两个数,每轮交换完可得到最大的数字排在最右边。
void bubble(){
int size = n;
for(int i = 1; i < n; i++){
for(int j = 1; j < size; j++){
if(a[j] < a[j - 1]) swap(a[j], a[j - 1]);
}
size--;
}
}
4. 快速排序
复杂度
先排序,后递归。每次处理将小于分界点的数放左边,大于分界点的数放右边。注意边界问题。
#include<iostream>
using namespace std;
const int N = 1000010;
int a[N];
void quick_sort(int l, int r){
if(l >= r) return;
int i = l - 1, j = r + 1, x = a[l + r >> 1];
while(i < j){
do i++; while(a[i] < x && i < r);
do j--; while(a[j] > x && j > l);
if(i < j) swap(a[i], a[j]);
}
quick_sort(l, j);
quick_sort(j + 1, r);
}
int main(){
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
quick_sort(0, n - 1);
for(int i = 0; i < n; i++) printf("%d ", a[i]);
return 0;
}
5. 归并排序
复杂度
先递归,后排序。每次处理将两个有序数组合并。注意将temp数组复制回原数组。
#include<iostream>
using namespace std;
const int N = 100010;
int a[N], tmp[N];
void merge_sort(int l, int r){
if(l >= r) return;
int mid = l + r >> 1;
merge_sort(l, mid);
merge_sort(mid + 1, r);
int i = l, j = mid + 1, c = 0;
while(i <= mid && j <= r){
if(a[i] <= a[j]) tmp[c++] = a[i++];
else tmp[c++] = a[j++];
}
while(i <= mid) tmp[c++] = a[i++];
while(j <= r) tmp[c++] = a[j++];
for(int i = l; i <= r; i++) a[i] = tmp[i - l];
}
int main(){
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
merge_sort(0, n - 1);
for(int i = 0; i < n; i++) printf("%d ", a[i]);
return 0;
}