十大排序算法
排序算法
排序算法 | 平均时间复杂度 | 最好情况 | 最坏情况 | 空间复杂度 | 排序方式 | 稳定性 |
---|---|---|---|---|---|---|
冒泡排序 | O(n^2) | O(n) | O(n^2) | O(1) | In-place | 稳定 |
选择排序 | O(n^2) | O(n^2) | O(n^2) | O(1) | In-place | 不稳定 |
插入排序 | O(n^2) | O(n) | O(n^2) | O(1) | In-place | 稳定 |
希尔排序 | O(n(logn)^2) | O(nlogn) | O(n(logn)^2) | O(1) | In-place | 不稳定 |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | Out-place | 稳定 |
快速排序 | O(nlogn) | O(nlogn) | O(n^2) | O(logn) | In-place | 不稳定 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | In-place | 不稳定 |
计数排序 | O(n + k) | O(n + k) | O(n + k) | O(k) | Out-place | 稳定 |
桶排序 | O(n + k) | O(n + k) | O(n^2) | O(n ) | Out-place | 稳定 |
基数排序 | O(n * k) | O(n * k) | O(n * k) | O(n + k) | Out-place | 稳定 |
冒泡排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for (int i = 0; i < n - 1; i ++ )
for (int j = 0; j < n - i - 1; j ++)
if (q[j] > q[j + 1])
swap(q[j], q[j + 1]);
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
- 优化版本
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for (int i = 0; i < n - 1; i ++)
{
bool flag = false;
for (int j = 0; j < n - 1 - i; j ++)
if (q[j] > q[j + 1])
{
swap(q[j], q[j + 1]);
flag = true;
}
if (!flag) break;
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
选择排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for (int i = 0; i < n - 1; i ++)
{
int minvIndex = i;
for (int j = i + 1; j < n; j ++)
if (q[j] < q[minvIndex])
minvIndex = j;
swap(q[minvIndex], q[i]);
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
插入排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, preIndex, curVal;
int q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for (int i = 1; i < n; i ++)
{
preIndex = i - 1;
curVal = q[i];
while (preIndex >= 0 && q[preIndex] > curVal)
{
q[preIndex + 1] = q[preIndex];
preIndex --;
}
q[preIndex + 1] = curVal;
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
希尔排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
for (int gap = n / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < n; i ++)
{
int j = i - gap, cur = q[i];
while (j >= 0 && cur < q[j])
{
q[j + gap] = q[j];
j -= gap;
}
q[j + gap] = cur;
}
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
归并排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N], temp[N];
void merge_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = l + r >> 1;
merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1;
while (i <= mid && j <= r)
{
if (q[i] < q[j]) temp[k ++] = q[i ++];
else temp[k ++] = q[j ++];
}
while (i <= mid) temp[k ++] = q[i ++];
while (j <= r) temp[k ++] = q[j ++];
for(int i = l, j = 0; i <= r; i ++, j ++)
q[i] = temp[j];
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
merge_sort(q, 0, n - 1);
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
快速排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n;
int q[N];
void quick_sort(int q[], int l, int r)
{
if (l >= r) return;
int mid = q[l + r >> 1], i = l - 1, j = r + 1;
while (i < j)
{
do i ++; while (q[i] < mid);
do j --; while (q[j] > mid);
if (i < j)
swap(q[i], q[j]);
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
scanf("%d", &q[i]);
quick_sort(q, 0, n - 1);
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
堆排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, m, len;
int h[N];
void down(int u)
{
int t = u;
if (u * 2 <= len && h[u * 2] < h[t]) t = u * 2;
if (u * 2 + 1 <= len && h[u * 2 + 1] < h[t]) t = u * 2 + 1;
if (u != t)
{
swap(h[u], h[t]);
down(t);
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++)
scanf("%d", &h[i]);
len = n;
for (int i = n / 2; i >= 1; i --)
down(i);
while (m --)
{
printf("%d ", h[1]);
h[1] = h[len --];
down(1);
}
return 0;
}
计数排序
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010, M = 10001;
int n, m; // m 就是存储元素的最大值
int q[N], bucket[M];
int main()
{
cin >> n;
for (int i = 0; i < n; i ++)
{
scanf("%d", &q[i]);
m = max(m, q[i]);
}
for (int i = 0; i < n; i ++)
bucket[q[i]] ++;
for (int i = 0, j = 0; i <= m; i ++)
while (bucket[i] > 0)
{
q[j ++] = i;
bucket[i] --;
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
计数排序必须先确定排序元素的最大值,然后开辟额外的空间来存储每个元素出现的次数。
桶排序
#include <iostream>
#include <algorithm>
#include <limits.h>
using namespace std;
const int N = 100010;
int n;
int q[N];
int main()
{
int maxv = INT_MIN, minv = INT_MAX;
cin >> n;
for (int i = 0; i < n; i ++)
{
scanf("%d", &q[i]);
maxv = max(maxv, q[i]);
minv = min(minv, q[i]);
}
// 计算桶的数量
int bucketNum = (maxv - minv) / n + 1;
vector<vector<int>> bucketArr(bucketNum);
// 将每个元素放入桶
for (int i = 0; i < n; i ++)
{
int num = (q[i] - minv) / n;
bucketArr[num].push_back(q[i]);
}
// 对每个桶进行排序
for (int i = 0; i < bucketNum; i ++)
sort(bucketArr[i].begin(), bucketArr[i].end());
// 将桶中的元素放入原数组
for (int i = 0, k = 0; i < bucketNum; i ++)
for (int j = 0; j < bucketArr[i].size(); j ++)
q[k ++] = bucketArr[i][j];
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
基数排序
#include <iostream>
#include <algorithm>
#include <limits.h>
using namespace std;
const int N = 100010;
int n;
int q[N], bucket[10], output[N];
int main()
{
cin >> n;
int maxv = INT_MIN;
for (int i = 0; i < n; i ++)
{
scanf("%d", &q[i]);
maxv = max(maxv, q[i]);
}
for (int exp = 1; maxv / exp > 0; exp *= 10)
{
for (int i = 0; i < n; i ++)
bucket[(q[i] / exp) % 10] ++;
for (int i = 1; i < 10; i ++)
bucket[i] += bucket[i - 1];
for (int i = n - 1; i >= 0; i --)
{
output[bucket[(q[i] / exp) % 10] - 1] = q[i];
bucket[(q[i] / exp) % 10] --;
}
for (int i = 0; i < n; i ++)
q[i] = output[i];
}
for (int i = 0; i < n; i ++)
printf("%d ", q[i]);
return 0;
}
基数排序的代码有点问题!