排序代码-存放点

如题,就存下各种排序的代码,方便以后快速回忆,包含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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值