各种排序算法的实现

来源:互联网 发布:电子烟 知乎 编辑:程序博客网 时间:2024/04/20 22:15

排序算法总结

最近在看算法导论,结合网上的信息总结一下排序算法。
相关文章:
http://blog.csdn.net/xiazdong/article/details/8462393
关于算法的不稳定性不是很理解,需要进一步加强。
https://visualgo.net/
很形象

排序算法复杂度

    int a[n] = { 6, 9, 2, 1 };    int b[n] = { 1, 2, 6, 9 };    int c[n] = { 9, 6, 2, 1 };

插入排序

void insert_sort(int arr[]){    cout << "insert sort:  "<<endl;    for (int i = 1; i < n; ++i)    {        int j = i - 1;        int key = arr[i];        while (j>=0 && arr[j] > key)        {            arr[j + 1] = arr[j];//将key之前的序列中大于key的值向后移动一位            --j;        }        arr[j + 1] = key;//将key移动到前边没有比key大的值得位置上        print_arr(arr);    }}

6 9 2 1
6 9 2 1 ->6 9 2 1
6 9 2 1 ->2 6 9 1
2 6 9 1 ->1 2 6 9

冒泡排序

void bubble_sort(int a[]){    cout << "bubble_sort: " << endl;    int temp;    for (int i = 0; i < n-1; ++i)    {        for (int j = n-1; j > i; --j)//要逆着排,这样才能把最小的排在最前边        {            if (a[j] < a[j-1])            {                temp = a[j];                a[j] = a[j-1];                a[j-1] = temp;            }            print_arr(a);        }    }}

6 9 2 1
6 9 2 1 -> 6 9 1 2
6 9 1 2 -> 6 1 9 2
6 1 9 2 -> 1 6 9 2
1 6 9 2 -> 1 6 2 9
1 6 2 9 -> 1 2 6 9
1 2 6 9 -> 1 2 6 9

选择排序

void select_sort(int a[]){    cout << "select sort:  " << endl;    for (int i = 0; i < n - 1; ++i)    {        int min = i;        for (int j = i + 1; j < n; ++j)        {            if (a[j] < a[min])                min = j;        }        swap(a[i], a[min]);        print_arr(a);    }}

6 9 2 1
6 9 2 1 ->6 9 2 1
6 9 2 1 ->2 9 6 1
2 9 6 1 ->1 9 6 2
1 9 6 2 ->1 6 9 2
1 6 9 2 ->1 2 9 6
1 2 9 6 ->1 2 6 9

/////////////快速排序////////////

int partition(int a[], int p, int q){    int i = p - 1;    int pivot = a[q];    for (int j = p; j < q ; ++j)    {        if (a[j] <= pivot)        {            i++;            swap(a[i], a[j]);//让子序列中的小于pivot的数放在前边        }    }    swap(a[i + 1], a[q]);    return i + 1;}void rescursive_quicksort(int a[], int p, int q){    if (p < q)    {        int r = partition(a, p, q);        rescursive_quicksort(a, p, r-1);        rescursive_quicksort(a, r + 1, q);        print_arr(a);    }}void quick_sort(int a[]){    rescursive_quicksort(a, 0, n-1);}

归并排序

void merge(int a[], int p, int q, int m){    int n1 = m - p + 1;    int n2 = q - m;    int *left = new int[n1];    int *right = new int[n2];    for (int i = 0; i < n1; ++i)        left[i] = a[p + i];    for (int i = 0; i < n2; ++i)        right[i] = a[m + i +1];    ////////////合并/////////    int i = 0;    int j = 0;    int k = p;    while (i<n1 && j < n2 && k<n)    {        if (left[i] < right[j])            a[k++] = left[i++];        else            a[k++] = right[j++];    }    while (i < n1) /* left[] is not exhausted */         a[k++] = left[i++];    while (j < n2) /* right[] is not exhausted */         a[k++] = right[j++];    print_arr(a);}void recursive_merge_sort(int a[], int p, int q){    if (p < q)    {        int m = (p + q) / 2 ;        recursive_merge_sort(a, p, m);        recursive_merge_sort(a, m + 1, q);        merge(a, p, q, m);        print_arr(a);    }}void merge_sort(int a[]){    cout << "merge sort: " << endl;    recursive_merge_sort(a, 0, n - 1);}

堆排序
两部分:(1) 形成最大堆(最顶端数最大),从底部向上计算
(2)将top移到最末,对于0~n-2的数组进行处理,形成新的最大堆

void heap_adjust(int a[], int s, int length)//序号s为根节点{    int temp = a[s];    int child = 2 * s + 1;    while (child < length)    {        if (child + 1<length && a[child]<a[child + 1])//比较两个子节点大小,得到值大的子节点            ++child;        if (a[s] < a[child])//如果根节点的值小于子节点的值,替换值并且更新根节点        {            a[s] = a[child];            s = child;            child = 2 * s + 1;        }        else            break;    a[s] = temp;//给以前的子节点(新的根节点赋原根节点的值)    }    print_arr(a);}void build_max_heap(int a[]){    for (int i = (n - 1) / 2; i >= 0; --i)//i为根节点序号,从底部算到上部        heap_adjust(a, i, n);}void heap_sort(int a[]){    build_max_heap(a);    for (int i = n - 1; i > 0; --i)    {        int temp = a[i];//把最后的值与第一个值(最大)替换        a[i] = a[0];        a[0] = temp;        heap_adjust(a, 0, i);///对0~i的长度的堆进行调整    }    print_arr(a);}

希尔排序
变步长的插入排序,这里我用的步长为n/2,n/4,…1

void shell_sort(int a[]){    for (int step = n; step > 0; step=step/2)//变步长的插入排序    {        for (int i = step; i < n; ++i)        {            int key = a[i];            int j = i-step;            while ( j>= 0 && a[j]>key)            {                a[j + step] = a[j];                j=j-step;            }            a[j + step] = key;        }        print_arr(a);    }}

计数排序
开辟一个count计数数组,统计原数组各个数的频数,累加得到累积频数,减一即在新数组中的位置。

void counting_sort(int a[],int k){    //int max = 0;    //for (int i = 0; i<n; ++i)    //{    //  if (a[i]>max)    //      max = a[i];    //}    //k = max + 1;    int *count = new int[k];    int *b = new int[n];    for (int i = 0; i < k; ++i)        count[i]=0;    for (int i = 0; i < n; ++i)        ++count[a[i]];    for (int i = 1; i < k; ++i)//从1开始算哦        count[i] = count[i] + count[i - 1];//统计不比a[i]大的数的个数,就是a[i]在新的数组中的位置    for (int i = n-1; i >=0; --i)    {        count[a[i]]--;//先减1,从零开始计数        b[count[a[i]]] = a[i];    }    print_arr(b);    delete count;    delete b;}

基数排序
先比个位(计数排序),然后依次十位,百位…

int* getBit(int a[], int bit_num){    int* b=new int[n];    for (int i = 0; i < n; ++i)    {        int total_bit_num = 0;        for (int no = a[i]; no > 0; no = no / 10)            total_bit_num++;        int p = pow(10, bit_num);        b[i] = a[i] /p %10;    }    return b;}void radix_sort(int a[]){    int max = find_max(a);    int bit_num = 0;    for (int i = max; i > 0; i = i / 10)        bit_num++;    int *num;    int *temp = new int[n];    int count[10];    for (int j = 0; j < bit_num; ++j)    {        for (int i = 0; i < 10; ++i)//清空计数数组            count[i] = 0;        num = getBit(a, j);//得到个位,十位...        for (int i = 0; i < n; ++i)            ++count[num[i]];                                           for (int i = 1; i < 10; ++i)//从1开始算哦            count[i] = count[i] + count[i - 1];//统计不比a[i]大的数的个数,就是a[i]在新的数组中的位置        for (int i = n-1; i >= 0 ; --i)//倒计算,假设两个相同的3正序算,第一个3会被放在后边,打乱了以前的排序        {            temp[count[num[i]]-1] = a[i];//先减1,从零开始计数            count[num[i]]--;        }        for (int i = 0; i < n; ++i)            a[i] = temp[i];        print_arr(a);    }    delete num;    delete temp;}
1 0