• 算法导论学习笔记(2)-归并排序


    今天学习了算法导论上的归并排序算法,而且完毕了在纸上写出伪代码,曾经就学过归并可是理解的不够透彻。

    前还一直困惑:为什么明明归并排序比快排的时间复杂度更稳定。为什么库函数不用归并而用快排。如今知道原因了,由于归并排序必须开额外的空间。并且空间开销还比較大,以下介绍算法:

    首先,归并排序用到了分治的思想。把大数据分成若干个小数据,然后再分别对小数据进行处理,最后把小数据

    合并成大数据。

    其次。归并排序用到了一个最重要的特点。就是把两组已经排序的数据合并成一组有序数据,而且该过程的时间复

    杂度为O(n)。

    最后,算法便出来了,对于一个数组A[n]来说,我们要对他进行排序,首先,我们如果A[0~n/2]和A[n/2+1,n-1]为

    有序序列,那么。我们就能够在O(n)的时间内排好序,但是。问题是,A[0~n/2]和A[n/2+1,n-1]并非有序序列,于是我们就要将他们都变成有序序列,怎样变呢?我们再分别对A[0~n/2]和A[n/2+1,n-1]进行排序就可以,对于A[0~n/2]来说,我们运用和以上同样的方法,把他分成A[0~n/2/2]和A[n/2+1,n/2],然后假设这两个数组均为有序序列的话,那么就能够把它们合并起来,然后在返回到上一层了。那么怎样才干推断他们为有序呢?当仅仅有一个元素的时候这个元素便是有序的。所以,仅仅须要递归到元素个数为1。然后再返回合并就可以。

    以下是对以下下代码中的merge()(合并)函数正确性的证明:

    1.当第一次循环迭代的时候,i = L, A[L, i-1]为空。是有序的序列(空也算有序序列),而且含有i-L=0个LA[n1],RA[n2]的最小的数,这时c1 = c2 = 0, LA[c1]和RA[c2]均为彼此数组中的最小的元素。

    2.如果第i次迭代的时候LA[c1] <= RA[c2], 这时LA[c1]便是还没有被拷贝到A中的最小的元素。此时A中含有i-L个最小的元素。当运行A[i] = LA[c1]时,A中便含有i-L+1个最小的元素,然后添加c1和i进行下一次迭代。如果第一次时LA[c1] > RA[c2]。运行相似的过程。

    3.循环结束后,i = r+1, 此时A中含有i-L = r-L+1个最小的元素。恰好是l~r全部的元素,而且已排好序,证毕。

    //insertion_sort
    #include <iostream>
    using namespace std;
    const int inf = (1<<28);
    
    void print(int* A, int n)
    {
        for (int i = 0; i < n; i++) {
            cout << A[i] << " ";
        }
        cout << endl;
    }
    void merge(int *A, int l, int m, int r)
    {
        int n1 = m-l+1, n2 = r-m;
        int lA[(const int)(n1+1)], rA[(const int)(n2+1)];
        for (int i = 0; i < n1; i++) {
            lA[i] = A[i+l];
        }
        for (int i = 0; i < n2; i++) {
            rA[i] = A[m+1+i];
        }
        lA[n1] = rA[n2] = inf;
        int c1 = 0, c2 = 0;
        for (int i = l; i <= r; i++)
        {
            if (lA[c1] <= rA[c2]) {
                A[i] = lA[c1++];
            }
            else {
                A[i] = rA[c2++];
            }
        }
    }
    void merge_sort(int *A, int l, int r)
    {
        if (l < r)
        {
            int m = (l + r) / 2;
            merge_sort(A, l, m);
            merge_sort(A, m+1, r);
            merge(A, l, m, r);
        }
    }
    int main()
    {
        int A[10] = {43,2,53,1,8,29,52,4,8,10};
        
        cout << "before sorted: ";
        print(A, 10);
        
        merge_sort(A, 0, 10);
        
        cout << "after sorted: ";
        print(A, 10);
        
        return 0;
    }
    




  • 相关阅读:
    Python安装
    solr集群solrCloud的搭建
    redis单机及其集群的搭建
    maven实现tomcat热部署
    maven发布时在不同的环境使用不同的配置文件
    nexus 的使用及maven的配置
    java 自定义注解以及获得注解的值
    Jenkins学习之——(4)Email Extension Plugin插件的配置与使用
    Jenkins学习之——(3)将项目发送到tomcat
    注意Tengine(Nginx) proxy_pass之后的"/"
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/7074201.html
Copyright © 2020-2023  润新知