基本排序算法

来源:互联网 发布:知其雄 编辑:程序博客网 时间:2024/05/07 22:17

代码:

#include <iostream>#include <vector>#include <algorithm>using namespace std;/*---------------------------改进冒泡排序------------------------------------*/// 算法复杂度O(n^2)vector<int> BubbleSort(vector<int> vec){    int length = vec.size();    bool flag = true;   //避免在剩余的数已经有序的情况下做无意义的循环判断    for (int i = 0; i < length; i++)    {        flag = false;        for (int j = length - 1; j > 0;j--)        {            if (vec[j] < vec[j-1])            {                swap(vec[j], vec[j -1]);                flag = true;            //如果有数据交换,则flag为true            }        }    }    return vec;}//简单选择排序, 算法复杂度O(n^2)vector<int> SimpleSelectionSort(vector<int> vec){    int length = vec.size();    int min = 0;        //保存每次找到的最小值的下标    for (int i = 0; i < length-1; i++)    {        min = i;        for (int j = i + 1; j < length; j++)        {            if (vec[j] < vec[min])            {                min = j;            }        }        if (i != min)            swap(vec[i], vec[min]);    }    return vec;}/*---------------------------简单插入排序------------------------------------*/// 算法复杂度O(n^2)vector<int> SimpleInsertSort(vector<int> vec){    int length = vec.size();    for (int i = 1, j = 0; i < length; i++)    {        if (vec[i] < vec[i - 1])        {            int temp = vec[i];            for (j = i - 1; j >= 0 && vec[j] > temp; j--)            {                vec[j + 1] = vec[j];            }            vec[j + 1] = temp;        }    }    return vec;}/*---------------------------希尔排序------------------------------------*///不稳定排序,算法复杂度O(n^(3/2))vector<int> ShellSort(vector<int> vec){    int j = 0;    int increment = vec.size();    do     {        increment = increment / 3 + 1;        for (int i = increment; i < vec.size() ; i++)        {            if (vec[i] < vec[i - increment])            {                int temp = vec[i];                for (j = i - increment; j >= 0 && temp < vec[j];j -= increment)                {                    vec[j + increment] = vec[j];                }                vec[j + increment] = temp;            }                   }    } while (increment > 1);    return vec;}/*---------------------------堆排序------------------------------------*///堆排序,不稳定排序算法,时间复杂度为O(nlogn)//不适合排序序列个数较少的情况,开始建堆所需的比较次数较多void swap(vector<int> &temp, int head, int last)    //交换堆顶与未经排序子序列的最后一个结点{    int tmp = temp[head];    temp[head] = temp[last];    temp[last] = tmp;}void HeapAdjust(vector<int> &vec, int low, int high){    int temp = vec[low];    for (int j = low * 2; j <= high; j *= 2)    {        if (j < high && vec[j] < vec[j + 1])            j++;        if (temp >= vec[j])            break;        vec[low] = vec[j];        low = j;    }    vec[low] = temp;  }vector<int> HeapSort(vector<int> vec){    vector<int> temp(vec.size() + 1, 0);    temp[0] = -1;    for (int i = 0; i < vec.size(); i++)    {        temp[i + 1] = vec[i];    }    //构建大根堆    for (int i = vec.size() / 2; i > 0; i--)    {        HeapAdjust(temp, i, vec.size());    }    //堆排序    for (int i = vec.size(); i > 1; i--)    {        swap(temp, 1, i);        HeapAdjust(temp, 1, i-1);    }    for (int i = 1; i < temp.size();i++)    {        vec[i - 1] = temp[i];    }    return vec;}/*---------------------------归并排序,递归实现------------------------------------*///合并void Merge(vector<int>& subvec, int p, int mid, int q){    int a = mid - p + 1;    int b = q - mid;    vector<int> L(a + 1, 0);    vector<int> R(b + 1, 0);    for (int i = 0; i < a; i++)        L[i] = subvec[p + i];    for (int j = 0; j < b; j++)        R[j] = subvec[mid + j + 1];    L[a] = R[b] = INT_MAX;    int i = 0, j = 0;    for (int k = p; k < q + 1; k++)    {        if (L[i] <= R[j])        {            subvec[k] = L[i];            i++;        }        else        {            subvec[k] = R[j];            j++;        }    }}//分解void RSort(vector<int> &subvec, int p, int q){    if (p < q)    {        int mid = (p + q) / 2;        RSort(subvec, p, mid);        RSort(subvec, mid + 1, q);        Merge(subvec, p, mid, q);       //合并    }}vector<int> MergeSort(vector<int> vec){    int length = vec.size();    RSort(vec,0,length-1);          //分解为多个子问题求解,分治思想    return vec;}/*---------------------------归并排序,非递归实现------------------------------------*///将有序的v1[i...m]和有序的v1[m+1...n]归并到有序的v2中void Merge2(vector<int>& v1, vector<int>& v2, int i, int m, int n){    int k = 0, j = 0;    for (k = i, j = m + 1; i <= m && j <= n; k++)    {        if (v1[i] < v1[j])            v2[k] = v1[i++];        else            v2[k] = v1[j++];    }    if (i <= m)    {        for (int t = 0; t <= m - i; t++)            v2[k+t] = v1[i+t];    }    if (j <= n)    {        for (int t = 0; t <= n-j; t++)            v2[k+t] = v1[j+t];    }}//将v1中相邻长度为gap的子序列两两归并到v2中void MergeAdjacent(vector<int>& v1, vector<int>& v2, int gap, int len) {    int i = 0;    while (i <= len-2*gap)    {        Merge2(v1, v2, i, i + gap - 1, i + 2 * gap - 1);        i += 2 * gap;    }    if (i < len - gap + 1 )         //当不够两组进行归并时,如果剩余元素超过k个元素,仍然进行归并        Merge2(v1, v2,i, i + gap - 1, len-1);    else                            //如果剩余元素不超过k个元素时,直接复制给中间数组    {        for (int j = i; j < len; j++)        {            v2[j] = v1[j];        }    }    for (i = 0; i < len; i++)        v1[i] = v2[i];}vector<int> MergeSort2(vector<int> vec){    int length = vec.size();    vector<int> vec2(length, 0);    int k = 1;    while (k < length)    {        MergeAdjacent(vec, vec2, k, length);        k = 2 * k;    }    return vec;}/*---------------------------快速排序------------------------------------*/int Partition(vector<int>& vec, int low, int high){    int pivotkey = vec[low];    //用子表中的第一个元素作为枢轴    while (low < high)    {        while (vec[high] >= pivotkey && low < high)            high--;        swap(vec[low], vec[high]);        while (vec[low] <= pivotkey && low < high)            low++;        swap(vec[low], vec[high]);    }    return low;}void QSort(vector<int>& vec, int low, int high){    int pivot;    if (low < high)    {        pivot = Partition(vec, low, high);  //算出中枢值        QSort(vec, low, pivot - 1);        QSort(vec, pivot + 1, high);    }}vector<int> QuickSort(vector<int> vec){    int length = vec.size();    QSort(vec, 0, length - 1);    return vec;}/*---------------------------计数排序------------------------------------*///算法复杂度O(n),线性时间排序算法,适合于小范围的集合的排序vector<int> CountSort(vector<int> vec){    int length = vec.size();    vector<int> result(length,0);   //保存结果    int max;    //保存最大值    //找出vec中的最大值    if (length > 0)    {         max = vec[0];        for (int i = 1; i < length; i++)        {            if (max < vec[i])                max = vec[i];        }    }    //创建保存计数的vector    vector<int> temp(max + 1, 0);    //保存最后结果    //vector<int> result;    for (int i = 0; i < length;i++)    {        temp[vec[i]] += 1;    }    //temp[i] 包含了小于等于i的个数,以确定i的位置    for (int i = 1; i <= max;i++)    {        temp[i] += temp[i - 1];    }    for (int j = length - 1; j >= 0;j--)    {        result[temp[vec[j]]-1] = vec[j];        temp[vec[j]] = temp[vec[j]] - 1;    }    return result;}/*---------------------------改进的计数排序------------------------------------*///与标准的相比,可以节约一些空间,vector<int> CountSort2(vector<int> vec){    int length = vec.size();    int max;    //保存最大值    //找出vec中的最大值    if (length > 0)    {        max = vec[0];        for (int i = 1; i < length; i++)        {            if (max < vec[i])                max = vec[i];        }    }    //创建保存计数的vector    vector<int> temp(max + 1, 0);    for (int i = 0; i < length; i++)    {        temp[vec[i]] += 1;    }    int j = 0;    for (int i = 0; i <= max; i++)    {        while (temp[i]--)            vec[j++] = i;    }    return vec;}/*---------------------------基数排序------------------------------------*///算法时间复杂度O(n),具有线性的时间代价//计数排序有两种方式,LSD由数值的最右边(低位)开始,而MSD则相反,由数值的最左边开始//LSD适用于位数少的数值,如果位数多,MSD的效率更好/*MSD实现是一个递归的过程:(1)首先根据最高位的关键码K1排序,得到若干个对象组,即分到若干个桶中,每个桶中有相同的关键字(2)再分别对每个桶根据关键码K2进行排序,再根据K2的分成若干个子桶,依次类推...(3)最后把所有桶中的序列连接起来既构成了一个有序的序列*///这里实现LSD,MSD类似//获取x这个数的第d位的数字//因为LSD由数值的最右边开始的,123的第1位为3,第二位为2,...int getDigit(int x, int d){    int a[] = { 1, 1, 10, 100 };    //本例中,最大数是百位数,因此a[]中最大为100    return (x / a[d] % 10);}vector<int> RadixSortLSD(vector<int> vec){    int length = vec.size();    int d = 3;      //本例中,最大的只有3位数    int count[10];  //每个桶排序    int j;    int* bucket = new int[length];    //对每位进行排序    for (int k = 1; k <= d; k++)    {        for (int i = 0; i < 10; i++)     //利用计数排序的思想用数组模拟桶            count[i] = 0;        //统计各个桶中所盛数据个数        for (int i = 0; i < length; i++)        {            count[getDigit(vec[i], k)]++;        }        for (int i = 1; i < 10; i++)            {            count[i] += count[i - 1];           }        //这时,count[i]表示第i个桶的右边界索引        for (int i = length - 1; i >= 0; i--)        {            j = getDigit(vec[i], k);            bucket[count[j] - 1] = vec[i];            count[j]--;        }        //此时,count[i]为第i个桶的左边界        //将桶中的数据收集出来        for (int i = 0, j = 0; i < length; i++, j++)            vec[i] = bucket[j];    }    delete[] bucket;    return vec;}int main(){    vector<int> array = { 9, 1, 5, 8, 3, 7, 4, 6, 2 };    vector<int> result;    //冒泡排序    result = BubbleSort(array);    cout << "冒泡排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //选择排序    result = SimpleSelectionSort(array);    cout << "简单选择排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //插入排序    result = SimpleInsertSort(array);    cout << "简单插入排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //希尔排序    result = ShellSort(array);    cout << "希尔排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //堆排序    result = HeapSort(array);    cout << "堆排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //归并排序,递归实现    result = MergeSort(array);    cout << "(递归实现)归并排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl<<endl;    //归并排序,非递归实现    result = MergeSort2(array);    cout << "(非递归实现)归并排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //快速排序    result = QuickSort(array);    cout << "快速排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl<<endl;    //计数排序    result = CountSort(array);    cout << "计数排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //计数排序2    result = CountSort2(array);    cout << "改进的计数排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    //基数排序    vector<int> array2 = { 329, 457, 657, 83, 436, 720, 355, 221, 983};    cout << "基数排序前: ";    for (auto it = array2.begin(); it != array2.end(); it++)        cout << *it << " ";    cout << endl;    result = RadixSortLSD(array2);    cout << "LSD基数排序后: ";    for (auto it = result.begin(); it != result.end(); it++)        cout << *it << " ";    cout << endl << endl;    system("pause");    return 0;}

测试:

这里写图片描述

0 0
原创粉丝点击