【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;
}

原文地址:https://www.cnblogs.com/DengSchoo/p/15390359.html