10大排序算法

本文详细介绍了C++中包括冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、堆排序、计数排序、桶排序和基数排序在内的10种排序算法的实现和工作原理。
摘要由CSDN通过智能技术生成

10大排序算法

冒泡排序

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>

void bubbleSort(std::vector<int> &v) {
    int n = v.size();
    if (n < 2) return;
    // 增加一个标志位 判断是否发生比较
    bool flag = false;
    // 总的趟数 n个数只需要比较n-1趟
    for (int i=n-1; i>0; --i) {
        flag = false;
        // 每一趟需要的次数为i次
        for (int j=0; j<i; ++j) {
            if (v[j] > v[j+1]) {
                int t = v[j];
                v[j] = v[j+1];
                v[j+1] = t;
                flag = true;
            }
        }

        if (!flag) return;
    }
}

int main() {
    srand(time(NULL));
    std::vector<int> v(10);
    for (int i=0; i<10; ++i) {
        v.push_back(rand());
    }

    printf("排序前:\n");
    for(const auto&i: v) {
        printf("%d ", i);
    }
    printf("\n");

    printf("排序后:\n");
    bubbleSort(v);
    for (const auto&i: v) {
        printf("%d ", i);
    }
    printf("\n");

    return 0;
}

选择排序

#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>

void selectSort(std::vector<int>& v) {
    if (v.size() < 2) return;
    int minPos = 0;
    for (int i=0; i<v.size()-1; ++i) {
        minPos = i;
        for (int j=i+1; j<v.size(); ++j) {
            if (v[j] < v[minPos]) {
                minPos = j;
            }
        }
        if (minPos != i) {
            int t = v[minPos];
            v[minPos] = v[i];
            v[i] = t;
        }
    }
}

void selectSort2(std::vector<int>& v) {
    int l = 0, r = v.size()-1;
    int minPos = 0, maxPos = 0;
    while (l < r) {
        minPos = maxPos = l;
        for(int i=l; i<=r; ++i) {
            if (v[i] < v[minPos]) minPos = i;
            if (v[i] > v[maxPos]) maxPos = i;
        }
        if (minPos != l) {
            int t = v[minPos];
            v[minPos] = v[l];
            v[l] = t;
        }

        // 若最左侧是最大数时,此时最大数位置已被换走
        if (maxPos == l) maxPos = minPos;

        if (maxPos != r) {
            int t = v[maxPos];
            v[maxPos] = v[r];
            v[r] = t;
        }

        ++l;
        --r;
    }
}

int main() {

    srand(time(nullptr));
    std::vector<int> v;
    for (int i=0; i<10; ++i) {
        v.push_back(rand() % 100);
    }

    printf("排序前\n");
    for (const auto& i:v) {
        printf("%d ", i);
    }
    printf("\n");

    // selectSort(v);
    selectSort2(v); // 优化后, 一次确定两个数

    printf("排序后\n");
    for (const auto&i: v) {
        printf("%d ", i);
    }
    return 0;
}

插入排序

#include <cstdio>
#include <ctime>
#include <cstdlib>


void insertSort(int arr[], int n) {
    int i=0, j=0;
    for (i=1; i<n; ++i) {
        int tmp = arr[i];       //记录待插入值
        for (j=i-1; (j>=0)&&(arr[j]>tmp); --j) {
            arr[j+1] = arr[j];  //从后往前 覆盖查找
        }
        arr[j+1] = tmp;
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    int n = sizeof(arr) / sizeof(int);
    for (int i=0; i<n; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before:\n");
    for (int i=0; i<n; ++i){
        printf("%d ", arr[i]);
    }
    printf("\n");
    insertSort(arr, n);
    printf("after:\n");
    for (int i=0; i<n; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

希尔排序

#include <cstdio>
#include <ctime>
#include <cstdlib>


void shellSort(int arr[], int n, int step) {
    int i=0, j=0;
    // 插入排序即可
    for (i=step; i<n; ++i) {
        int tmp = arr[i];
        for (j=i-step; j>=0&&arr[j]>tmp; j-=step) {
            arr[j+step] = arr[j];
        }
        arr[j+step] = tmp;
    }     
}

void shell(int arr[], int n) {
    // shell step
    for (int step=n/2; step>0; step/=2) {
        shellSort(arr, n, step);
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    int n = sizeof(arr) / sizeof(int);
    for (int i=0; i<n; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before:\n");
    for (int i=0; i<n; ++i){
        printf("%d ", arr[i]);
    }
    printf("\n");
    shell(arr, n);
    printf("after:\n");
    for (int i=0; i<n; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

快速排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

int partition(int* arr, int low, int high) {
    int pivot = arr[low];
    int left = low, right = high;
    while (left<right) {
        while (left<right && arr[right]>=pivot) right--;
        arr[left] = arr[right];

        while (left<right && arr[left]<=pivot) left++;
        arr[right] = arr[left];
    }
    arr[left] = pivot;
    return left;
}

void quickSort(int* arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi+1);
        quickSort(arr, pi+1, high);
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    memset(arr, 0, sizeof(arr));
    int len = sizeof(arr) / sizeof(int);
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for(int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    quickSort(arr, 0, len-1);

    printf("after: \n");
    for (int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
   

归并排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

void merge(int* arr, int low, int mid, int high) {
    int tmp[high-low+1], k = 0;
    int i=low, j=mid+1;

    while (i<=mid && j<=high) {
        tmp[k++] = arr[i]<=arr[j] ? arr[i++] : arr[j++];
    }
    while (i<=mid) {
        tmp[k++] = arr[i++];
    }
    while (j<=high) {
        tmp[k++] = arr[j++];
    }
    memcpy(arr+low, tmp, sizeof(tmp));
}

void mergeSort(int* arr, int low, int high) {
    if (low < high) {
        int mid = low + (high-low) / 2;
        mergeSort(arr, low, mid);
        mergeSort(arr, mid+1, high);

        merge(arr, low, mid, high);
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    memset(arr, 0, sizeof(arr));
    int len = sizeof(arr) / sizeof(int);
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for(int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    mergeSort(arr, 0, len-1);

    printf("after: \n");
    for (int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
   

堆排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

void swap(int* a, int* b) {
    int t = *a;
    *a = *b;
    *b = t;
}

void heapfy(int* arr, int i, int n) {
    int father = i;
    int son = 2*father+1;
    while (son <= n) {
        if (son+1<=n && arr[son+1]>arr[son]) son++;
        if (arr[father] > arr[son]) return;
        swap(&arr[son], &arr[father]);
        father = son;
        son = 2*father+1;
    }
}

void heapSort(int* arr, int len) {
    for (int i=(len-1)/2; i>=0; --i) heapfy(arr, i, len-1);
    for (int i=len-1; i>0; --i) {        // 下沉
        swap(&arr[0], &arr[i]);
        heapfy(arr, 0, i-1);        // i-1代表每次排序好一个数
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    memset(arr, 0, sizeof(arr));
    int len = sizeof(arr) / sizeof(int);
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for(int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    heapSort(arr, len);
    printf("排序后\n");
    for (int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

计数排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

int argMax(int* arr, int len) {
    int maxValue = -1;
    for (int i=0; i<len; ++i) {
        maxValue = arr[i] > maxValue ? arr[i] : maxValue;
    }
    return maxValue;
}

void countSort(int* arr, int len) {
    int maxValue = argMax(arr,len);
    int tmp[maxValue+1];
    memset(tmp, 0, sizeof(tmp));
    for (int i=0; i<len; ++i) {
        tmp[arr[i]]++;
    }
    for (int i=0, k=0; i<maxValue+1; ++i) {
        while (tmp[i]--) {
            arr[k++] = i;
        }
    }
}

int main() {
    srand(time(NULL));
    int arr[10] = {0};
    memset(arr, 0, sizeof(arr));
    int len = sizeof(arr) / sizeof(int);
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for(int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    countSort(arr, len);

    printf("after: \n");
    for (int i=0; i<len; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
   

桶排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

int partition(int* arr, int low, int high) {
    int pivot = arr[low];
    int left = low, right = high;
    while (left < right) {
        while (left<right && arr[right]>=pivot) right--;
        arr[left] = arr[right];

        while (left<right && arr[left]<=pivot) left++;
        arr[right] = arr[left];
    }
    arr[left] = pivot;
    return left;
}

void quickSort(int* arr, int low, int high) {
    if (low < high) {
        int pi = partition(arr, low, high);
        quickSort(arr, low, pi-1);
        quickSort(arr, pi+1, high);
    }
}

void bucketSort(int* arr, int len) {
    int bucket[len][len];
    int bucketSize[len];

    memset(bucket, 0, sizeof(bucket));
    memset(bucketSize, 0,sizeof(bucketSize));

    for (int i=0; i<len; ++i) {
        bucket[arr[i]/10][bucketSize[arr[i]/10]++] = arr[i];
    }

    // 对每个桶调用一次排序算法
    for (int i=0; i<len; ++i) {
        quickSort(bucket[i], 0, bucketSize[i]-1);
    }

    for(int i=0, k=0; i<len; ++i) {
        for (int j=0; j<bucketSize[i]; ++j) {
            arr[k++] = bucket[i][j];
        }
    }
}

int main() {

    srand(time(NULL));
    int arr[10];
    int len = sizeof(arr) / sizeof(int);
    memset(arr, 0, sizeof(arr));
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for (const auto&i: arr) {
        printf("%d ", i);
    }
    printf("\n");
    bucketSort(arr, len);
    printf("after: \n");
    for (const auto&i: arr) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

基数排序

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

void argMax(int* arr, int len, int& maxValue) {
    for (int i=0; i<len; ++i) {
        maxValue = arr[i] > maxValue ? arr[i] : maxValue;
    }
}

void _radixSort(int* arr, int len, int exp) {
    int result[len];        // 暂存临时结果
    int bucket[10];         // 10个桶
    memset(result, 0, sizeof(result));
    memset(bucket, 0, sizeof(bucket));

    for (int i=0; i<len; ++i) {         // 记录每个桶记录末尾数的个数
        bucket[(arr[i]/exp)%10]++;
    }

    for (int i=1; i<10; ++i) {          // 精妙之处 累加刚好是len
        bucket[i] += bucket[i-1];
    }

    for (int i=len-1; i>=0; --i) {
        int iexp = (arr[i]/exp)%10;
        result[bucket[iexp]-1] = arr[i];        // 刚好是该数字所在的下标
        bucket[iexp]--;
    }

    memcpy(arr, result, sizeof(result));    // 每一轮的值拷过去
}

void radixSort(int* arr, int len) {
    int maxValue = 0;
    argMax(arr, len, maxValue);

    for (int exp=1; maxValue/exp>0; exp*=10) {
        _radixSort(arr, len, exp);
    }
}


int main() {

    srand(time(NULL));
    int arr[10];
    int len = sizeof(arr) / sizeof(int);
    memset(arr, 0, sizeof(arr));
    for (int i=0; i<len; ++i) {
        arr[i] = rand() % 100;
    }
    printf("before: \n");
    for (const auto&i: arr) {
        printf("%d ", i);
    }
    printf("\n");

    radixSort(arr, len);

    printf("after: \n");
    for (const auto&i: arr) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值