常见排序的指针实现【C++ Code】

本来是想加上传cmp函数的,后来也懒得写了
然后基数排序虽然写的是模板类,但也只是支持整数了…

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <typeinfo>
using namespace std;
const int MAX_N = 500 + 10;
template <class T>
class MySort{
public :
    MySort();
    static void select_sort(T *_left, T *_right);
    static void bubble_sort(T *_left, T *_right);
    static void insert_sort(T *_left, T *_right);
    static void radix_sort(T *_left, T *_right);
    static void quick_sort(T *_left, T *_right);
    static void merge_sort(T *_left, T *_right);
    static int cmp(const T &a, const T& b){ //默认比较函数
        if (a == b) return 0;
        return a > b ? 1 : -1;
    }
private :
    static void print(char *ch, int *a, int n){ //输出中间排序结果
        printf("%s",ch);
        for (int i = 0;i < n;i++)
            printf("%d ",a[i]);
        printf("\n");
    }
};

template <class T>
void MySort<T>::select_sort(T *_left, T *_right) //选择排序
{
    for (T *_point = _left; _point != _right; ++_point){
        T *_tmp = _point;
        for (T *_next = _point + 1; _next != _right; ++_next){ //从无序部分选择出一个最小的元素
            if (cmp(*_tmp, *_next) > 0){
                _tmp = _next;
            }
        }
        swap(*_tmp, *_point); //放入有序部分的最后
        print("SelectSort: ",_left, _right - _left);
    }
}
template <class T>
void MySort<T>::bubble_sort(T *_left, T *_right) //冒泡排序
{
    for (T *_point = _left; _point != _right - 1; ++_point){
        for (T *_next = _point + 1; _next != _right; ++_next){
            if (cmp(*_point, *_next) > 0){  //比较相邻元素,若前面的大于后面的元素,交换它们的位置.
                swap(*_point, *_next);
            }
        }
        print("BubbleSort: ",_left, _right - _left);
    }
}
template <class T>
void MySort<T>::insert_sort(T *_left, T *_right) //插入排序
{
    for (T *_point = _left + 1; _point != _right; ++_point){
        T _tmp = *_point;
        for (T *_next = _point - 1; _next != _left - 1; --_next){
            if (cmp(_tmp, *_next) < 0){ //如果该元素比_tmp大,将_tmp向后挪一位
                *(_next + 1) = *_next;
            }else {                     //否则将该元素插入到_next+1位置.
                *(_next + 1) = _tmp;
                break;
            }
        }
        print("InsertSort: ",_left, _right - _left);
    }
}
template <class T>
void MySort<T>::radix_sort(T *_left, T *_right) //基数排序
{
    int n = _right - _left, *a = _left;
    int b[n];
    int m = *_left, exp = 1;
    for (int i = 1; i < n; i++){ //选择出最大的元素
        if (cmp(m,a[i]) < 0)
            m = a[i];
    }
    while (m / exp > 0){
        int bucket[10] = {0};
        for (int i = 0; i < n; i++) bucket[(a[i] / exp) % 10]++; //对每个数的某位进行桶排
        for (int i = 1; i < 10; i++) bucket[i] += bucket[i - 1];
        for (int i = n - 1; i >= 0; i--)
            b[--bucket[(a[i] / exp) % 10]] = a[i];
        for (int i=0;i<n;i++) a[i] = b[i]; //从桶中取出元素
        print("RadixSort: ",a, n);
        exp *= 10;
    }
}
template <class T>
void MySort<T>::quick_sort(T *_left, T *_right) //快速排序
{

    if (_left >= _right) return;
    T *_first = _left, *_last = _right, *_tmp = _left + ((_right - _left)>> 1); //确定基准元素
    while (_first < _last){ //让基准元素左边的元素逗比它小,右边的元素都比它大
        while ((cmp(*_first, *_tmp) < 0) && (_first < _last)) _first++;
        while ((cmp(*_last, *_tmp) > 0) && (_first < _last)) _last--;
        if (_first <= _last) {
            swap(*_first, *_last);
            _first++;
            _last--;
        }
    }
    quick_sort(_left, _last); //递归调用
    quick_sort(_first, _right);
    print("QuickSort: ",_left,_right - _left + 1);
}
template <class T>
void MySort<T>::merge_sort(T *_left, T *_right) //归并排序
{
    if (_left >= _right) return;

    T *_mid = _left + ((_right - _left) >> 1);
    merge_sort(_left, _mid); //递归调用排序
    merge_sort(_mid + 1, _right);
    T *_low = _left , *_high = _mid + 1; //已经得到两个有序的部分

    T tmp[_right - _left + 1] = {0};
    int  cnt = 0;
    while (_low <= _mid && _high <= _right){ //进行合并,先存到tmp数组
        if (cmp(*_low, *_high) < 0){
            tmp[cnt] = *_low;
            _low++;
        }else {
            tmp[cnt] = *_high;
            _high++;
        }
        cnt++;
    }
    for (int i = 0; i <= _mid - _low; i++)
        tmp[cnt++] = *(_low + i);
    for (int i = 0; i <= _right - _high; i++)
        tmp[cnt++] = *(_high + i);
    for (int i = 0; i < cnt; i++) *(_left + i) = tmp[i]; //放回原位置
    print("MergeSort: ",_left,_right - _left + 1);
}

int a[MAX_N], b[MAX_N];
int main()
{
    int n;
    scanf("%d",&n);
    for (int i=0;i<n;i++) {
        scanf("%d", a + i);
        b[i] = a[i];
    }
    MySort<int>::select_sort(b, b + n);
    puts("");
    for (int i=0;i<n;i++) b[i] = a[i];
    MySort<int>::radix_sort(b, b + n);
    puts("");
    for (int i=0;i<n;i++) b[i] = a[i];
    MySort<int>::insert_sort(b, b + n);
    puts("");
    for (int i=0;i<n;i++) b[i] = a[i];
    MySort<int>::bubble_sort(b, b + n);
    puts("");
    for (int i=0;i<n;i++) b[i] = a[i];
    MySort<int>::quick_sort(b, b + n - 1);
    puts("");
    for (int i=0;i<n;i++) b[i] = a[i];
    MySort<int>::merge_sort(b, b + n - 1);
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值