排序算法(C++)

比较类排序

交换排序

冒泡排序

void bubble_sort(int arr[], int low, int high) {
    int len = high-low+1;
    for (int i = 0; i < len-1; ++i) {
        for (int j = 0; j < len-1-i; ++j) {
            if (arr[j+low] > arr[j+1+low]) {
                swap(arr[j+low],arr[j+1+low]);
            }
        }
    }
}

快速排序

void quick_sort(int arr[], int low, int high) {
    if (low >= high) return;
    int i = low, j = high, tmp = arr[low];
    while (i < j) {
        while (i < j && arr[j] >= tmp) j--;
        arr[i] = arr[j];
        while (i < j && arr[i] <= tmp) i++;
        arr[j] = arr[i];
    }
    arr[i] = tmp;
    quick_sort(arr, low, i-1);
    quick_sort(arr, i+1, high);
}

插入排序

简单插入排序

void insert_sort(int arr[], int low, int high) {
    for (int i = low+1; i <= high; ++i) {
        int tmp = arr[i], j;
        for (j = i-1; j >= low; --j) {
            if (arr[j] <= tmp) break;
            arr[j+1] = arr[j];
        }
        arr[j+1] = tmp;
    }
}

希尔排序

void shell_sort(int arr[], int low, int high) {
    int len = high-low+1;
    for (int t = len/2; t > 0; t /= 2) {
        for (int i = low+t; i <= high; ++i) {
            int tmp = arr[i], j;
            for (j = i-t; j >= low; j -= t) {
                if (arr[j] <= tmp) break;
                arr[j+t] = arr[j];
            }
            arr[j+t] = tmp;
        }
    }
}

选择排序

简单选择排序

void select_sort(int arr[], int low, int high) {
    for (int i = low; i <= high-1; ++i) {
        int min_index = i;
        for (int j = i+1; j <= high; ++j) {
            if (arr[min_index] > arr[j]) {
                min_index = j;
            }
        }
        swap(arr[min_index],arr[i]);
    }
}

堆排序

void heapify(int arr[], int root, int low, int len) {
    int left = 2*root+1;
    int right = 2*root+2;
    int max_index = root;
    if (left < len && arr[left+low] > arr[max_index+low]) max_index = left;
    if (right < len && arr[right+low] > arr[max_index+low]) max_index = right;

    // 如果需要调整
    if (max_index != root) {
        // 交换父节点和子节点的值
        swap(arr[root+low],arr[max_index+low]);
        // 判断子节点是否需要交换
        heapify(arr, max_index, low, len);
    }
}
void build_max_heap(int arr[], int low, int len) {
    // 从最后一个非叶节点开始向前遍历,调整成为大顶堆
    for (int i = len/2-1; i >= 0; --i) {
        heapify(arr, i, low, len);
    }
}
void heap_sort(int arr[], int low, int high) {  // [low,high]
    int len = high-low+1;
    build_max_heap(arr, low, len);
    for (int i = len-1; i > 0; --i) {
        swap(arr[0+low],arr[i+low]);
        len--;
        heapify(arr, 0, low, len);
    }
}

归并排序

void merge(int arr[], int tmp[], int low, int high) {
    if (low >= high) return;
    int mid = low + (high-low)/2;
    merge(arr, tmp, low, mid);
    merge(arr, tmp, mid+1, high);

    int i = low, j = mid+1, k = low;
    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++];
    for (k = low; k <= high; ++k) arr[k] = tmp[k];
}
void merge_sort(int arr[], int low, int high) {
    int tmp[high-low+1];
    merge(arr, tmp, low, high);
}

非比较类排序

计数排序

void counting_sort(int arr[], int low, int high, int max_num) {
    int tmp[max_num+1];
    memset(tmp,0,sizeof(tmp));
    for (int i = low; i <= high; ++i) {
        tmp[arr[i]]++;
    }
    int j = low;
    for (int i = 0; i <= max_num; ++i) {
        while (tmp[i]--) arr[j++] = i;
    }
}

桶排序

void bucket_sort(int arr[], int low, int high) {
    // 找出最大最小值
    int max_num = arr[low];
    int min_num = arr[low];
    for (int i = low+1; i <= high; ++i) {
        max_num = max(max_num, arr[i]);
        min_num = min(min_num, arr[i]);
    }
    // 计算桶的数量
    int len = high-low+1;
    int bucket_num = (max_num-min_num)/len + 1;
    vector<int> bucket_arr[bucket_num];
    // 将每个元素放入桶
    for (int i = low; i <= high; ++i) {
        int num = (arr[i]-min_num) / len;
        bucket_arr[num].push_back(arr[i]);
    }
    // 对每个桶进行排序,可以使用快排
    for (int i = 0; i < bucket_num; ++i) {
        sort(bucket_arr[i].begin(),bucket_arr[i].end());
    }
    // 将桶中的元素赋值到原序列
    int k = low;
    for (int i = 0; i < bucket_num; ++i) {
        for (int j = 0; j < bucket_arr[i].size(); ++j) {
            arr[k++] = bucket_arr[i][j];
        }
    }
}

基数排序

void radix_sort(int arr[], int low, int high, int max_digit) {
    int mod = 10;
    int dev = 1;
    for (int i = 0; i < max_digit; ++i, dev *= 10, mod *= 10) {
        vector<int> counter[10];
        for (int j = low; j <= high; ++j) {
            int bucket = (arr[j]%mod)/dev;
            counter[bucket].push_back(arr[j]);
        }
        int pos = low;
        for (int j = 0; j < 10; ++j) {
            for (int k = 0; k < counter[j].size(); ++k) {
                arr[pos++] = counter[j][k];
            }
        }
    }
}

快速排序优化

#include <bits/stdc++.h>
using namespace std;
int arr[1000005];

// 插入排序
void insert_sort(int arr[], int low, int high) {
    for (int i = low+1; i <= high; ++i) {
        int tmp = arr[i], j;
        for (j = i-1; j >= low; --j) {
            if (arr[j] <= tmp) break;
            arr[j+1] = arr[j];
        }
        arr[j+1] = tmp;
    }
}

// 快速排序
void quick_sort(int arr[], int low, int high) {
    if (low >= high) return;

    // 序列长度少时使用插入排序
    if (high - low < 20) {
        insert_sort(arr,low,high);
        return;
    }

    // 三数取中,并将中间值放在最左边
    int mid = low + (high-low)/2;
    if (arr[mid] > arr[high]) swap(arr[mid],arr[high]);
    if (arr[low] > arr[high]) swap(arr[low],arr[high]);
    if (arr[mid] > arr[low]) swap(arr[low],arr[mid]);

    // 快排
    int i = low, j = high, tmp = arr[low];
    while (i < j) {
        while (i < j && arr[j] >= tmp) j--;
        arr[i] = arr[j];
        while (i < j && arr[i] <= tmp) i++;
        arr[j] = arr[i];
    }
    arr[i] = tmp;
    quick_sort(arr, low, i-1);
    quick_sort(arr, i+1, high);
}

int main() {
    for (int i = 0; i < 1000000; ++i) arr[i] = 99999999-i;
    // srand(1);  // 设置随机种子
    // random_shuffle(arr,arr+1000000);  // 打乱序列

    clock_t startTime, endTime;
    startTime = clock();
    quick_sort(arr, 0, 999999);
    endTime = clock();
    cout << "quick_sort run time: " << (endTime-startTime)/1000.0 << endl;

    return 0;
}
posted @ 2020-08-17 19:34  麻辣猪仔  阅读(163)  评论(0编辑  收藏  举报