常用排序算法C++版小结

来源:互联网 发布:shift 在js中 编辑:程序博客网 时间:2024/05/18 09:39

常用排序算法及其时间复杂度和空间复杂度

代码来自网络和日常整理:

#include <iostream>using std::cout;inline void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; }//AVG: O(n*n) WOREST: O(n*n), Space: O(1), Ascendvoid bubbleSort(int *arr, int len);//AVG: O(n*n) WOREST: O(n*n), Space: O(1), Ascendvoid selectSort(int *arr, int len);//AVG: O(n*n) WOREST: O(n*n), Space: O(1), Ascendvoid insertSort(int *arr, int len);//AVG: O(n*logn) WOREST: <O(n*n), Space: O(1), Ascendvoid shellSort(int *arr, int len);//AVG: O(n*logn) WOREST: O(n*n), Space: O(n*logn), Ascendvoid quickSort(int *arr, int start, int end);//AVG: O(n*logn) WOREST: O(n*logn), Space: O(1), Ascendvoid mergeSort(int *arr, int start, int end);void mergeSort2(int *arr, int start, int mid, int end);//AVG: O(n*logn) WOREST: O(n*logn), Space: O(1), Ascendvoid heapSort(int *arr, int len);void heapSort2(int *arr, int idx, int len);//大根堆, 根节点的值大于子节点//基数排序的时间复杂度表达式不好写,见下文//AVG: WOREST:,Space: O(n), Ascendint GetLoopCnt(int *arr, int len);void radixSort(int *arr, int len);int main(){    int array[] = {1, 3, 4, 2, 1, 3, 5, 8, 9, 6};    int len = sizeof(array)/sizeof(int);    cout << "Before sorting:\n";    std::copy(array, array+len, std::ostream_iterator<int>(cout, "\t"));    cout << '\n';    //bubbleSort(array, len);    //selectSort(array, len);    //quickSort(array, 0, len-1);    //mergeSort(array, 0, len-1);    //insertSort(array, len);    //shellSort(array, len);    //heapSort(array, len);    radixSort(array, len);    cout << "After sorting:\n";    std::copy(array, array+len, std::ostream_iterator<int>(cout, "\t"));    cout << '\n';}void bubbleSort(int *arr, int len){    bool flag = true;    for(int i=0; i<len-1 && flag; i++) {        flag = false;        for(int j=0; j<len-i-1; j++) {            if(arr[j]>arr[j+1]) {                swap(arr[j], arr[j+1]);                flag = true;            }                      }    }}void selectSort(int *arr, int len){    for(int i=0; i<len-1; i++) {        int min = arr[i];        int index = i;        for(int j=i+1; j<len; j++) {            if(min>arr[j]) {                min = arr[j];                index = j;            }                      }        if(index != i) {            swap(arr[i], arr[index]);        }    }}void quickSort(int *arr, int start, int end){    int i = start;    int j = end;    int key = arr[i];    while(i<j) {        while(i<j && arr[j]>=key) j--;            arr[i] = arr[j];        while(i<j && arr[i]<=key) i++;            arr[j] = arr[i];    }//找到 key对应的支点位置    arr[i] = key;    //递归调用, 注意递归调用条件,去除支点    if(i-1 >start) quickSort(arr, start, i-1);    if(i+1 < end) quickSort(arr, i+1, end);}void mergeSort(int *arr, int start, int end){    if(start < end) {        int mid = start + (end-start)/2;        mergeSort(arr, start, mid);        mergeSort(arr, mid+1 , end);        mergeSort2(arr, start, mid, end);    }}void mergeSort2(int *arr, int start, int mid, int end){    int ls = mid-start+1;    int rs = end-mid;    int *left = new int[ls];    int *right = new int[rs];    int i=0, j=0, k=start;    while(i<ls) left[i++] = arr[k++];    while(j<rs) right[j++] = arr[k++];    i=0;     j=0;     k=start;    while(i<ls && j<rs) {        arr[k++] = (left[i]>right[j]) ? (right[j++]) : (left[i++]);    }    while(i<ls) arr[k++] = left[i++];    while(j<rs) arr[k++] = right[j++];    delete[] left;    delete[] right;}void insertSort(int *arr, int len){    for(int i=1; i<len; i++) {        int tmp = arr[i];        int j=i;        while(j>0 && arr[j-1]>tmp) {            arr[j] = arr[j-1];             j--;        }        arr[j] = tmp;    }}void shellSort(int *arr, int len){    for(int gap=len/2; gap>=1; gap/=2) {        for(int i=gap; i<len; i++) {            for(int j=i-gap; j>=0; j-=gap) {                if(arr[j]>arr[j+gap])                    swap(arr[j], arr[j+gap]);            }        }    }}void heapSort(int *arr, int len){    //建立大根堆    for(int i=len/2-1; i>=0; i--)        heapSort2(arr, i, len);    for(int i=len-1; i>0; i--) {        swap(arr[0], arr[i]);//获得根节点值        heapSort2(arr, 0, i);//以剩余元素新建大根堆    }}void heapSort2(int *arr, int idx, int len){    int left = 2*idx + 1;    int right = left + 1;    int max = idx;    if(left<len && arr[left]>arr[max]) max = left;    if(right<len && arr[right] > arr[max]) max = right;    if(max != idx) {        swap(arr[idx], arr[max]);        heapSort2(arr, max, len);    }}int GetLoopCnt(int *arr, int len){    int n=1, tmp = 10;    for(int i=0; i<len; i++) {        int absval = abs(arr[i]);        while( absval > tmp ) {            ++n;            tmp*=10;        }    }    return n;}void radixSort(int *arr, int len){    int n = GetLoopCnt(arr, len);    const int radixCnt = 19;    const int base = 10;    int radix = 1;    int* num = new int[len];    int* tmp = new int[len];    for(int i=0; i<n; ++i) {        int count[radixCnt] = {0};        int j=0;        for (; j<len; ++j) {            num[j] = 9 + (arr[j]/radix)%10;            ++count[num[j]];        }        for(j=1; j<radixCnt; ++j) {            count[j] += count[j-1];        }        for(j=len-1; j>=0; j--) {            tmp[--count[num[j]]] = arr[j]; //不懂你在干什么        }        for(j=0; j<len; j++)             arr[j] = tmp[j];        radix *= base;    }    delete[] num;    delete[] tmp;}

PS: 基数排序平均时间复杂度:O(logR B),最坏时间复杂度::O(logR B).
另外时间复杂度与初始排序无关的算法包括: 选择排序, 堆排序, 归并排序和基数排序.

0 0