常见几种排序算法的C++描述

首先看一下几种常见排序的特性

这里写图片描述

插入排序

void insertSort(vector<int> & arr)
{
    int sz = arr.size();
    int tmp;
    for (int i = 1; i < sz; ++i){
        tmp = arr[i];
        int j;
        for (j = i; j > 0 && tmp < arr[j - 1]; j--)
            arr[j] = arr[j - 1];
        arr[j] = tmp;
    }
}

快速排序

//注意如果采取的是三数中值分割法的时候需要,将头,中,尾的三个值中间的转移到数组的头部。这样来进行partition
void quickSort(vector<int> & arr, int start, int end)
{
    if (start >= end)
        return;
    int pivot = getPartion(arr, start, end);
    quickSort(arr, start, pivot - 1);
    quickSort(arr, pivot + 1, end);
}


void bubbleSort(vector<int> & arr)
{
    int sz = arr.size();
    for (int i = sz - 1; i > 0; --i){
        for (int j = 0; j < i; ++j){ //边界需要注意一下
            if (arr[j] > arr[j + 1])
                swap(arr[j], arr[j+1]);
        }
    }
}

希尔排序

void shellSort(vector<int> & arr)
{
    int sz = arr.size();
    for (int gap = sz / 2; gap > 0; gap /= 2){
        int tmp;
        for (int i = gap; i < sz; ++i){//每次和保证自己同样的间隔组中数据是有序的,然后再使用插入排序的思想
            tmp = arr[i];
            int j;
            for (j = i; j >= gap && tmp < arr[j - gap]; j -= gap){
                arr[j] = arr[j - gap];
            }
            arr[j] = tmp;
        }
    }
}

堆排序

int up(int i){
    return (i - 1) / 2; //堆节点从0开始计算
}

int down(int i){
    return i * 2 + 1; //左节点
}

//添加数据用
void minHeapFixUp(vector<int> & arr, int i)//i代表插入的位置
{
    int j = up(i);
    int tmp = arr[i];
    while (j >= 0 && i != 0){
        if (arr[j] <= arr[i])
            break; //停止调整
        arr[i] = arr[j];
        i = j;
        j = up(i);
    }
    arr[i] = tmp;
}

//删除数据用,实际上是通过删除操作来调整堆
void minHeapFixDown(vector<int> & arr, int i, int n)
{
    int tmp = arr[i];
    int j = down(i);
    while (j < n){
        if (j + 1 < n && arr[j] > arr[j + 1])
            j++;
        if (tmp <= arr[j])
            break;
        arr[i] = arr[j];
        i = j;
        j = down(j);
    }
    arr[i] = tmp;
}

void makeHeap(vector<int> & arr)
{
    int sz = arr.size();
    //从sz/2 - 1开始建堆的目的是因为对于堆来说,有sz/2 + 1个节点是叶子节点,
    //由于其左右不存在子节点,不需要向下调整,所以从非叶子节点开始向下调整
    for (int i = sz / 2 - 1; i >= 0; --i){
        minHeapFixDown(arr, i, sz);
    }
}

void heapSort(vector<int> & arr)//最小堆得到降序排序
{
    int sz = arr.size();
    makeHeap(arr);
    for (int i = sz - 1; i > 0; --i){
        swap(arr[0], arr[i]); //得到最小的一个数
        minHeapFixDown(arr, 0, i);
    }
}

归并排序

void merge(vector<int> & arr, vector<int> & copy, int start, int mid, int end)
{
    int p = start, q = mid + 1, i = start;
    while (p <= mid && q <= end){
        if (arr[p] < arr[q])
            copy[i++] = arr[p++];
        else
            copy[i++] = arr[q++];
    }
    while (p <= mid)
        copy[i++] = arr[p++];
    while (q <= end)
        copy[i++] = arr[q++];
    while (start <= end){
        arr[start] = copy[start];
        start++; //注意这里一定要分开写  而不要合在一起,容易加两次出错
    }
}

void mergeSort(vector<int> & arr, vector<int> & copy, int start, int end)
{
    if (start < end){
        int mid = (start + end) >> 1;
        mergeSort(arr, copy, start, mid);
        mergeSort(arr, copy, mid + 1, end);
        merge(arr, copy, start, mid, end);
    }
}

void mergeSort(vector<int> & arr)
{
    vector<int> copy(arr);
    int sz = arr.size();
    int mid = sz / 2;
    mergeSort(arr, copy, 0, mid);
    mergeSort(arr, copy, mid + 1, sz - 1);
    merge(arr, copy, 0, mid, sz - 1);
}

直接选择排序

void selectSort(vector<int> & vec){
    int sz = vec.size();
    int minPos;
    for (int i = 0; i < sz - 1; ++i){
        minPos = i;
        for (int j = i + 1; j < sz; ++j){
            if (vec[j] < vec[minPos])
                minPos = j;
        }
        swap(vec[i], vec[minPos]);
    }
}

基数排序

  • 分别按照个位,十位,百位。。。来进行桶排序,得到最终结果就是正确的结果
public class RadixSort {
    // 获取x这个数的d位数上的数字
    // 比如获取123的1位数,结果返回3
    public int getDigit(int x, int d) {
        int a[] = {
                1, 1, 10, 100
        }; // 本实例中的最大数是百位数,所以只要到100就可以了
        return ((x / a[d]) % 10);
    }
    public void radixSort(int[] list, int begin, int end, int digit) {
        final int radix = 10; // 基数
        int i = 0, j = 0;
        int[] count = new int[radix]; // 存放各个桶的数据统计个数
        int[] bucket = new int[end - begin + 1];
        // 按照从低位到高位的顺序执行排序过程
        for (int d = 1; d <= digit; d++) {
            // 置空各个桶的数据统计
            for (i = 0; i < radix; i++) {
                count[i] = 0;
            }
            // 统计各个桶将要装入的数据个数
            for (i = begin; i <= end; i++) {
                j = getDigit(list[i], d);
                count[j]++;
            }
            // count[i]表示第i个桶的右边界索引
            for (i = 1; i < radix; i++) {
                count[i] = count[i] + count[i - 1];
            }
            // 将数据依次装入桶中
            // 这里要从右向左扫描,保证排序稳定性
            for (i = end; i >= begin; i--) {
                j = getDigit(list[i], d); // 求出关键码的第k位的数字, 例如:576的第3位是5
                bucket[count[j] - 1] = list[i]; // 放入对应的桶中,count[j]-1是第j个桶的右边界索引
                count[j]--; // 对应桶的装入数据索引减一
            }
            // 将已分配好的桶中数据再倒出来,此时已是对应当前位数有序的表
            for (i = begin, j = 0; i <= end; i++, j++) {
                list[i] = bucket[j];
            }
        }
    }
    public int[] sort(int[] list) {
        radixSort(list, 0, list.length - 1, 3);
        return list;
    }
    // 打印完整序列
    public void printAll(int[] list) {
        for (int value : list) {
            System.out.print(value + "\t");
        }
        System.out.println();
    }
    public static void main(String[] args) {
        int[] array = {
                50, 123, 543, 187, 49, 30, 0, 2, 11, 100
        };
        RadixSort radix = new RadixSort();
        System.out.print("排序前:\t\t");
        radix.printAll(array);
        radix.sort(array);
        System.out.print("排序后:\t\t");
        radix.printAll(array);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值