七大排序算法C++实现(代码分享)
By qianghaohao(Xqiang)
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
//****************************************************************************
// Author: qianghaohao(Xqiang)
// Mail: qiang.timothy@qq.com
//****************************************************************************
// 直接插入排序
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
// 稳定性:稳定
void InsertSort(vector<int> &a, const int &n) {
for (int i = 1; i < n; i++) {
int key = a[i];
// 找插入位置
int j = i - 1;
for ( ; j >= 0; j--) {
if (key < a[j]) {
a[j+1] = a[j];
} else {
break;
}
}
a[j+1] = key;
}
}
// 折半插入排序
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
// 稳定性:稳定
void BinaryInsertSort(vector<int> &a, const int &n) {
for (int i = 1; i < n; i++) {
int key = a[i];
int low = 0;
int high = i - 1;
// 二分法找插入位置
while (low <= high) {
int mid = low + ((high - low) >> 2);
if (key < a[mid]) {
high = mid - 1;
} else {
low = mid + 1;
}
}
for (int j = i - 1; j >= low; j--) {
a[j+1] = a[j];
}
a[low] = key;
}
}
// 希尔排序:
// a:数组 d:分组间距 n:元素个数
// 时间复杂度:O(2^1.5)
// 空间复杂度:O(1)
// 稳定性:不稳定
void ShellSort(vector<int> &a, int d, const int &n) {
int i, j, key;
while (d > 0) {
for (i = d; i < n; i++) {
key = a[i];
for (j = i - d; j >= 0; j -= d) {
if (key < a[j]) {
a[j+d] = a[j];
} else {
break;
}
}
a[j+d] = key;
}
d -= 2; //最终要保证d为1
}
}
// 冒泡排序
// 时间复杂度:O(n^2)
// 稳定性:稳定
void BubbleSort(vector<int> &a, const int &n) {
for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (a[j] > a[j+1]) {
swap(a[j], a[j+1]);
}
}
}
}
// 选择排序
// 时间复杂度:O(n^2)
// 空间复杂度:O(1)
// 稳定性:不稳定
void SelectSort(vector<int> &a, const int &n) {
for (int i = 0; i < n - 1; i++) {
vector<int>::iterator it = std::min_element(a.begin() + i, a.end()); //选最小值
swap(a[i], a[it - a.begin()]); //最小值和a[i]交换
}
}
快速排序
时间复杂度:O(nlogn)
稳定性:不稳定
//void QuickSort(vector<int> &a, int low, int high) {
// int i = low;
// int j = high;
// if (i < j) {
// while (i < j) { //i == j跳出循环
// //支点为i
// while (i < j && a[i] <= a[j]) {
// j--;
// }
// if (i < j) {
// swap(a[i], a[j]);
// i++;
// }
// //支点为j
// while (i < j && a[i] <= a[j]) {
// i++;
// }
// if (i < j) {
// swap(a[i], a[j]);
// j--;
// }
// }
// QuickSort(a, low, i-1);
// QuickSort(a, i+1, high);
// }
//}
// 快速排序(改进版--避免了交换支点的开销)
// 时间复杂度:O(nlogn)
// 空间复杂度:O(nlogn)
// 稳定性:不稳定
void QuickSort(vector<int> &a, int low, int high) {
int i = low;
int j = high;
if (i < j) {
int pivot = a[i]; //保存支点
while (i < j) { //i == j跳出循环
//支点为i
while (i < j && pivot <= a[j]) {
j--;
}
if (i < j) {
a[i] = a[j];
i++;
}
//支点为j
while (i < j && a[i] <= pivot) {
i++;
}
if (i < j) {
a[j] = a[i];
j--;
}
}
a[i] = pivot; //i==j时填入支点
QuickSort(a, low, i-1);
QuickSort(a, i+1, high);
}
}
// 堆排
// 时间复杂度:O(nlogn)
// 空间复杂度:O(1)
// 稳定性:不稳定
// 不适合在元素个数太少的情况
// 调整堆为最大堆
void AdjustHeap(vector<int> &a, int n) {
int i, j;
for (i = (n - 1) / 2; i > 0; i--) { //(n-1)/2:最后一个有孩子节点的编号
j = 2*i; //左孩子
if (j + 1 <= n-1) { //左右孩子都有
if (a[j+1] > a[j]) { //选取左右孩子中较大的
j = j + 1;
}
}
//******************************************
// 交换--较大的元素调整到根节点
// 在此也可以用a[0]当作中间变量来交换
// 相当于temp,因为a[0]在整个排序过程中
// 没有使用
//******************************************
if (a[i] < a[j]) {
swap(a[i], a[j]);
}
}
}
// 调用AdjustHeap进行堆排
void HeapSort(vector<int> &a, int n) {
for (int i = 0; i < n-1; i++) {
AdjustHeap(a, n - i);
swap(a[1], a[n-1-i]);
}
}
// 归并排序
// 时间复杂度:O(nlogn)
// 空间复杂度:O(n)
// 稳定性:稳定
// 将src中low-mid 和 mid-high两部分合并
void MergeArray(vector<int> &src, int low, int mid, int high, vector<int> &des) {
int i = low;
int j = mid; //前半部分
int m = mid + 1; //后半部分
int n = high;
int k = 0;
while (i <= j && m <= n) {
if (src[i] < src[m]) {
des[k++] = src[i++];
} else {
des[k++] = src[m++];
}
}
// 合并可能剩余元素
while (i <= j) {
des[k++] = src[i++];
}
while (m <= n) {
des[k++] = src[m++];
}
swap_ranges(src.begin() + low, src.begin() + high + 1, des.begin()); // 合并后放回原数组
}
// temp:临时向量,保存合并后的元素
void MergeSort(vector<int> &a, int first, int last, vector<int> &temp) {
int mid;
if (first < last) {
mid = first + ((last - first) >> 1);
MergeSort(a, first, mid, temp);
MergeSort(a, mid + 1, last, temp);
MergeArray(a, first, mid, last, temp);
}
}
// 测试用例
int main() {
vector<int> arr = {9, 8, 7, 6, 5, 4, 4, 4, 6, 6, 6};
vector<int> temp(arr.size()); //merge sort test
// vector<int> arr = {0, 9, 8, 7, 6, 5, 4, 4, 4, 6, 6, 6}; //heap sort test
// InsertSort(arr, arr.size());
// BinaryInsertSort(arr, arr.size());
// ShellSort(arr, 5, arr.size());
// BubbleSort(arr, arr.size());
// SelectSort(arr, arr.size());
// QuickSort(arr, 0, arr.size()-1);
// HeapSort(arr, arr.size());
// copy(arr.begin() + 1, arr.end(), ostream_iterator<int>(cout, " ")); //heap sort test
MergeSort(arr, 0, arr.size()-1, temp);
copy(arr.begin(), arr.end(), ostream_iterator<int>(cout, " "));
return 0;
}
各大排序算法性能对比: