如题,就存下各种排序的代码,方便以后快速回忆,包含9种排序
quickSort(data, 0, n - 1); 快排
mergeSort(data, 0, n - 1); 归并
heapSort(data, n); 堆排
countSort(data, n); 计数
bubbleSort(data, n); 冒泡
selectSort(data, n); 选择
radixSort(data, n); 基数
insertSort(data, n); 插入
shellSort(data, n); 希尔
完整代码如下
#include <iostream>
#include <algorithm>
#include <math.h>
#include <cmath>
using namespace std;
const int maxN = 555;
const int maxM = 230000;
//************* 快排 nglogn 不稳定 ***********//
int partition(int *data,int low,int high){
int key = data[low];
while(low < high){
while(low < high && data[high] >= key) high--;
data[low] = data[high];
while(low < high && data[low] <= key) low++;
data[high] = data[low];
}
data[low] = key;
return low;
}
//[0,n-1] 闭区间
void quickSort(int *data,int low,int high){
if(low < high){
int mid = partition(data,low,high);
quickSort(data,low,mid - 1);
quickSort(data,mid + 1 ,high);
}
}
//************* 归并 nglogn 稳定排序 ************//
//************* 将两部分有序数组进行合并,一直选最小的 ************//
void merge(int *data,int low,int mid,int high){
int *tmp = new int [high - low + 1];
int idx = 0, left = low, right = mid + 1;
while(left <= mid && right <= high){
if(data[left] < data[right]) tmp[idx++] = data[left++];
else tmp[idx++] = data[right++];
}
//剩余的一方全加进来
while(left <= mid) tmp[idx++] = data[left++];
while(right <= high) tmp[idx++] = data[right++];
for (int i = 0; i < idx; ++i) {
data[low + i] = tmp[i];
}
}
void mergeSort(int *data,int low,int high){
if(low < high){
int mid = (low + high) / 2;
mergeSort(data,low,mid);
mergeSort(data,mid + 1,high);
merge(data,low,mid,high);
}
}
//************* 堆 nlogn 不稳定 ************//
//************* build最大堆,然后每次把堆顶放到最后面 ************//
void headAdjust(int *data,int begin,int end){ //[begin,end)
int cur = begin;
int son = 2 * cur + 1;
while(son < end){
if(son + 1 < end && data[son] < data[son + 1]) son++;
if(data[son] < data[cur]) return;
swap(data[cur],data[son]);
cur = son;
son = 2 * cur + 1;
}
}
void heapSort(int *data,int n){ //[0,n)
for (int i = n / 2; i >= 0; --i) {
headAdjust(data,i, n);
}
for (int i = n - 1; i >= 0; --i) {
swap(data[0],data[i]);
headAdjust(data,0,i);
}
}
//************* 计数排序 O(n) 换个写法倒序填就是稳定排序 ************//
//************* 对每个数计数,遍历数字本身,按出现次数来放回到数组里 ************//
void countSort(int *data,int n){
int nmax = data[0],nmin = data[0];
for (int i = 0; i < n; ++i) {
nmax = max(data[i],nmax);
nmin = min(data[i],nmin);
}
int *times = new int[nmax + 1];
memset(times,0,sizeof(times)* (nmax + 1));
for (int i = 0; i < n; ++i) {
times[data[i]] ++;
}
int cnt = 0;
for (int num = nmin; num <= nmax; ++num) {
for (int i = 1; i <= times[num]; ++i) {
data[cnt++] = num;
}
}
}
//************* 冒泡 n*n 稳定排序 ************//
//************* 不断把大的数字都往后边传递,小的就自然留前面了 ************//
void bubbleSort(int *data,int n){ //[0,n)
for (int i = 0; i < n -1 ; ++i) {
for (int j = 0; j < n - i - 1; ++j) {
if(data[j] > data[j+1]){
swap(data[j],data[j+1]);
}
}
}
}
//************* 选择 n*n 不稳定排序 ************//
//************* 每次选出最小的,放前面 ************//
void selectSort(int *data,int n){ //[0,n)
for (int i = 0; i < n ; ++i) {
int minIndex = i;
for (int j = i; j < n ; ++j) {
if(data[j] < data[minIndex]){
minIndex = j;
}
}
swap(data[minIndex],data[i]);
}
}
//************* 插入排序 n*n 稳定排序 ************//
//************* 找到第一个小于新数字的位置,把这后面的数字都往后挪,留个空位出来 *************//
void insertSort(int *data,int n){ //[0,n)
int j;
for (int i = 1; i < n ; ++i) {
int tmp = data[i];
for (j = i - 1; j >= 0 && data[j] > tmp; --j) {
data[j + 1] = data[j];
}
data[j + 1] = tmp;
}
}
void insertSort2(int *data,int n){ //[0,n)
int j;
for (int i = 1; i < n ; ++i) {
int tmp = data[i];
for (j = i; j > 0 && data[j - 1] > tmp; --j) {
data[j] = data[j - 1];
}
data[j] = tmp;
}
}
//************* 希尔排序 1.3n 不稳定排序 ************//
//************* 按一定距离进行插入排序,不断缩减到1 ************//
void shellSort(int *data,int n){ //[0,n)
int j;
for(int dis = n / 2 ; dis > 0; dis /= 2){
for (int i = dis; i < n ; ++i) {
int tmp = data[i];
for (j = i - dis; j >= 0 && data[j] > tmp; j -= dis) {
data[j+dis] = data[j];
}
data[j+dis] = tmp;
}
}
}
//************* 基数排序 O (n * log(r)m) r为基数,m为堆数 稳定排序 ************//
/**
基数排序原理上基于两个事实:
1. 一堆N位的数字,我们分别按照个位、十位、百位这样每一位去排原数字,当排好全部位的时候整个结果就是有序。那么我们的问题就变成了如何按每一位去排序。
2. 一位数的排序,我们可以通过计数的方案,比如0-9排序,我们算出0有5个,1有3个,2有2个。那么所有个位为1的数字放的位置就是在下标从5到8号(0开始),数字8我们累加5+3就有了,至于5不需要管,个位为1的就3个,从8倒序放,一个个减到0就是了。
**/
void radixSort(int *data,int n){ //[0,n)
int RADIX = 10;
int *bucket = new int [n];
int times[RADIX];
int pos = 1;
int maxLen = 1 ,maxVal = data[0];
for (int i = 0; i < n; ++i) {
maxVal = max(maxVal,data[i]);
}
while(maxVal / pos > 0) { //循环 最大位数 次
memset(times,0,sizeof(times));
for (int i = 0; i < n; ++i) {
times[ data[i] / pos % RADIX ] ++;
}
for (int i = 1; i < RADIX; ++i) {
times[i] = times[i - 1] + times[i];
}
for (int i = n - 1; i >= 0; --i) {
int location = data[i] / pos % RADIX;
bucket[ times[location] - 1 ] = data[i];
times[location] --;
}
for (int i = 0; i < n; ++i) {
data[i] = bucket[i];
}
pos *= 10;
}
}
void printArr(int *data,int n){
for (int i = 0; i < n; ++i) {
cout<< data[i] << " ";
}
cout << endl;
cout << endl;
}
int main() {
int data[] = {1, 5, 6, 7, 3, 2, 10, 9, 0, 231, 3214, 61};
// int data[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
int n = sizeof(data) / sizeof(int);
printArr(data,n);
quickSort(data, 0, n - 1);
// mergeSort(data, 0, n - 1);
// heapSort(data, n);
// countSort(data, n);
// bubbleSort(data, n);
// selectSort(data, n);
// radixSort(data, n);
// insertSort(data, n);
// shellSort(data, n);
// cout << sort(data, n) << endl;
printArr(data,n);
return 0;
}