• 【Algorithm】Sorting Algorithm


    【Algorithm】Sorting Algorithm

    目录

    • 对比排序
      • 冒泡排序Bubble Sort
      • 归并排序Merge Sort
      • 快速排序Quick Sort
    • 线性排序
      • 计数排序Count Sort
      • 桶排序Bucket Sort

    对比排序

    Bubble Sort

    /*
     * 冒泡排序:重复得走过要排序的数列 每次比较相邻的两个元素 如果顺序错误则交换 大的数会冒泡到底端
     */
    void bubbleSort(vector<int> &arr) {
            int temp = 0;
            bool swap;
            for (int i = arr.size() - 1; i > 0; i--) { // 每次需要排序得长度
                    swap = false;
                    for (int j = 0; j < i; j++) { // 从第1个元素到第i个元素
                            if (arr[j] > arr[j + 1]) {
                                    ::swap(arr[j], arr[j + 1]);
                                    swap = 1;
                            }
                    }
                    if (!swap) break; // 优化:如果有序就不需要再排序
            }
    }
    

    Merge Sort

    /*
     * 归并排序:将数据切分为一半 对每一半进行排序 最后合并(递归)
     */
    // 合并两个有序数组
    void mergeSortedArray(vector<int> &arr, vector<int> &tmp, int left, int mid, int right) {
            int i = left, j = mid + 1, k = 0;
            // 处理两个公共的长度
            while (i <= mid && j <= right) {
                    tmp[k++] = arr[i] < arr[j] ? arr[i++]:arr[j++];
            }
            // 处理剩余的左区间
            while (i <= mid) tmp[k++] = arr[i++];
            // 处理剩余的右区间
            while (j <= right) tmp[k++] = arr[j++];
    
            // 复制回原数组
            for (int i = 0; i < k; i++) {
                    arr[left + i] = tmp[i];
            }
    }
    
    void internalMergeSort(vector<int> &arr, vector<int> &tmp, int left, int right) {
            if (left < right) {
                    int mid = (left + right) >> 1;
                    internalMergeSort(arr, tmp, left, mid);
                    internalMergeSort(arr, tmp, mid + 1, right);
                    mergeSortedArray(arr, tmp, left, mid, right);
            }
    }
    
    void mergeSort(vector<int> &arr){
            vector<int> tmp(arr.size(), 0);
            internalMergeSort(arr, tmp, 0, arr.size() - 1);
    }
    
    

    快速排序

    /*
     * 快速排序:在待排序的数组中选择一个元素为基准 将待排序的元素分区 大于基准的在右边
     */
    int partition(vector<int> &arr, int low, int high) {
            int pivot = arr[low];
            while (low < high) {
                    while (low < high && arr[high] >= pivot) high--;
                    arr[low] = arr[high];
                    while (low < high && arr[low] <= pivot) low++;
                    arr[high] = arr[low];
            }
            arr[low] = pivot;
            return low;
    }
    void quick_sort(vector<int> &arr, int low, int high) {
            if (low >= high) return;
            int pivot = partition(arr, low, high);
            quick_sort(arr, low, pivot);
            quick_sort(arr, pivot + 1, high);
    }
    void quickSort(vector<int> &arr) {
            quick_sort(arr, 0, arr.size() - 1);
    }
    

    线性排序

    Count Sort

    /*
     * 计数排序
     * 统计数组中的最大值最小值 然后统计每个元素中出现的次数 反向填充目标数组
     */
    
    void countSort(vector<int> &arr) {
            int MAX = INT_MIN;
            int MIN = INT_MAX;
    
            for (int i = 0; i < arr.size(); i++) {
                    MAX = max(MAX, arr[i]);
                    MIN = min(MIN, arr[i]);
            }
            vector<int> tmp(arr.size(), 0);
            vector<int> count(MAX - MIN + 1, 0);
    
            for (int i = 0; i < arr.size(); i++) {
                    count[arr[i] - MIN]++; // 此时count[i]表示等于i的个数
            }
    
            for (int i = MIN + 1; i <= MAX; i++) {
                    count[i - MIN] += count[i - MIN - 1]; //  count[i]表示小于等于i的元素个数
            }
    
            for (int i = 0; i < arr.size(); i++) {
                    int num = arr[i];
                    int idx = count[num - MIN] - 1; // 前面有几个元素
                    tmp[idx] = num;
                    count[num - MIN]--; //  前面元素减少1
            }
            for (int i = 0; i < arr.size(); i++) {
                    arr[i] = tmp[i];
            }
    }
    

    Bucket Sort

    /*
     * 桶排序:桶自有序 计算每个元素属于哪个桶 每个桶各自排序放入数组中
     */
    void bucketSort(vector<int> &arr) {
            int MAX = INT_MIN;
            int MIN = INT_MAX;
    
            for (int i = 0; i < arr.size(); i++) {
                    MAX = max(MAX, arr[i]);
                    MIN = min(MIN, arr[i]);
            }
            int bucketNum = (MAX - MIN) / arr.size() + 1;
            vector<vector<int>> bucketArr(bucketNum);
    
            for (int i = 0; i < arr.size(); i++) {
                    int num = (arr[i] - MIN) / arr.size();
                    bucketArr[num].push_back(arr[i]);
            }
    
            // 对每个桶排序
            int cnt = 0;
            for (int i = 0; i < bucketNum; i++) {
                    sort(bucketArr[i].begin(), bucketArr[i].end());
                    for (int j = 0; j < bucketArr[i].size(); j++) {
                            arr[cnt++] = bucketArr[i][j];
                    }
            }
    }
    

    完整代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    /*
     * 比较算法:
     *      1. 冒泡
     *      2. 归并排序
     *      3. 快速排序
     * 线性算法:
     *      1. 计数排序
     *      2. 桶排序
     */
    const int N = 9;
    
    vector<int> arr = {2 , 3, 1, 4 , 6, 7, 5, 8, 5};
    
    void init(vector<int> &arr) {
            arr = {2 , 3, 1, 4 , 6, 7, 5, 8, 5};
    }
    
    void print(vector<int> arr) {
            for (auto x : arr) {
                    printf("%d ", x);
            }
            cout << endl;
    }
    
    /*
     * 冒泡排序:重复得走过要排序的数列 每次比较相邻的两个元素 如果顺序错误则交换 大的数会冒泡到底端
     */
    void bubbleSort(vector<int> &arr) {
            int temp = 0;
            bool swap;
            for (int i = arr.size() - 1; i > 0; i--) { // 每次需要排序得长度
                    swap = false;
                    for (int j = 0; j < i; j++) { // 从第1个元素到第i个元素
                            if (arr[j] > arr[j + 1]) {
                                    ::swap(arr[j], arr[j + 1]);
                                    swap = 1;
                            }
                    }
                    if (!swap) break; // 优化:如果有序就不需要再排序
            }
    }
    
    /*
     * 归并排序:将数据切分为一半 对每一半进行排序 最后合并(递归)
     */
    // 合并两个有序数组
    void mergeSortedArray(vector<int> &arr, vector<int> &tmp, int left, int mid, int right) {
            int i = left, j = mid + 1, k = 0;
            // 处理两个公共的长度
            while (i <= mid && j <= right) {
                    tmp[k++] = arr[i] < arr[j] ? arr[i++]:arr[j++];
            }
            // 处理剩余的左区间
            while (i <= mid) tmp[k++] = arr[i++];
            // 处理剩余的右区间
            while (j <= right) tmp[k++] = arr[j++];
    
            // 复制回原数组
            for (int i = 0; i < k; i++) {
                    arr[left + i] = tmp[i];
            }
    }
    
    void internalMergeSort(vector<int> &arr, vector<int> &tmp, int left, int right) {
            if (left < right) {
                    int mid = (left + right) >> 1;
                    internalMergeSort(arr, tmp, left, mid);
                    internalMergeSort(arr, tmp, mid + 1, right);
                    mergeSortedArray(arr, tmp, left, mid, right);
            }
    }
    
    void mergeSort(vector<int> &arr){
            vector<int> tmp(arr.size(), 0);
            internalMergeSort(arr, tmp, 0, arr.size() - 1);
    }
    
    
    /*
     * 快速排序:在待排序的数组中选择一个元素为基准 将待排序的元素分区 大于基准的在右边
     */
    int partition(vector<int> &arr, int low, int high) {
            int pivot = arr[low];
            while (low < high) {
                    while (low < high && arr[high] >= pivot) high--;
                    arr[low] = arr[high];
                    while (low < high && arr[low] <= pivot) low++;
                    arr[high] = arr[low];
            }
            arr[low] = pivot;
            return low;
    }
    void quick_sort(vector<int> &arr, int low, int high) {
            if (low >= high) return;
            int pivot = partition(arr, low, high);
            quick_sort(arr, low, pivot);
            quick_sort(arr, pivot + 1, high);
    }
    void quickSort(vector<int> &arr) {
            quick_sort(arr, 0, arr.size() - 1);
    }
    
    /*
     * 计数排序
     * 统计数组中的最大值最小值 然后统计每个元素中出现的次数 反向填充目标数组
     */
    
    void countSort(vector<int> &arr) {
            int MAX = INT_MIN;
            int MIN = INT_MAX;
    
            for (int i = 0; i < arr.size(); i++) {
                    MAX = max(MAX, arr[i]);
                    MIN = min(MIN, arr[i]);
            }
            vector<int> tmp(arr.size(), 0);
            vector<int> count(MAX - MIN + 1, 0);
    
            for (int i = 0; i < arr.size(); i++) {
                    count[arr[i] - MIN]++; // 此时count[i]表示等于i的个数
            }
    
            for (int i = MIN + 1; i <= MAX; i++) {
                    count[i - MIN] += count[i - MIN - 1]; //  count[i]表示小于等于i的元素个数
            }
    
            for (int i = 0; i < arr.size(); i++) {
                    int num = arr[i];
                    int idx = count[num - MIN] - 1; // 前面有几个元素
                    tmp[idx] = num;
                    count[num - MIN]--; //  前面元素减少1
            }
            for (int i = 0; i < arr.size(); i++) {
                    arr[i] = tmp[i];
            }
    }
    
    /*
     * 桶排序:桶自有序 计算每个元素属于哪个桶 每个桶各自排序放入数组中
     */
    void bucketSort(vector<int> &arr) {
            int MAX = INT_MIN;
            int MIN = INT_MAX;
    
            for (int i = 0; i < arr.size(); i++) {
                    MAX = max(MAX, arr[i]);
                    MIN = min(MIN, arr[i]);
            }
            int bucketNum = (MAX - MIN) / arr.size() + 1;
            vector<vector<int>> bucketArr(bucketNum);
    
            for (int i = 0; i < arr.size(); i++) {
                    int num = (arr[i] - MIN) / arr.size();
                    bucketArr[num].push_back(arr[i]);
            }
    
            // 对每个桶排序
            int cnt = 0;
            for (int i = 0; i < bucketNum; i++) {
                    sort(bucketArr[i].begin(), bucketArr[i].end());
                    for (int j = 0; j < bucketArr[i].size(); j++) {
                            arr[cnt++] = bucketArr[i][j];
                    }
            }
    }
    
    
    int main() {
            //bubbleSort(arr);
    
            //mergeSort(arr);
    
            //quickSort(arr);
    
            //countSort(arr);
    
            bucketSort(arr);
            print(arr);
            init(arr);
            return 0;
    }
    
    
  • 相关阅读:
    最长上升子序列问题总结
    Problem C
    Problem C
    Problem P
    Problem P
    Problem H
    Problem H
    Problem D
    Problem D
    Linux系统调用--getrlimit()与setrlimit()函数详解
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/15390359.html
Copyright © 2020-2023  润新知