• 归并排序


    归并排序是创建在归并操作上的一种有效的排序算法,效率为O(nlogn),1945年由冯·诺伊曼首次提出。

      归并排序的实现分为递归实现非递归(迭代)实现。递归实现的归并排序是算法设计中分治策略的典型应用,我们将一个大问题分割成小问题分别解决,然后用所有小问题的答案来解决整个大问题。非递归(迭代)实现的归并排序首先进行是两两归并,然后四四归并,然后是八八归并,一直下去直到归并了整个数组。

      归并排序算法主要依赖归并(Merge)操作。归并操作指的是将两个已经排序的序列合并成一个序列的操作,归并操作步骤如下:

    1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置
    3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    4. 重复步骤3直到某一指针到达序列尾
    5. 将另一序列剩下的所有元素直接复制到合并序列尾

       首先考虑下如何将将二个有序数列合并。这个非常简单,只要从比较二个数列的第一个数,谁小就先取谁,取了后就在对应数列中删除这个数。然后再进行比较,如果有数列为空,那直接将另一个数列的数据依次取出即可。

    //将有序数组a[]和b[]合并到c[]中  
    void MemeryArray(int a[], int n, int b[], int m, int c[])  
    {  
        int i, j, k;  
      
        i = j = k = 0;  
        while (i < n && j < m)           //选取a  b中较小的元素放在前面
        {  
            if (a[i] < b[j])  
                c[k++] = a[i++];  
            else  
                c[k++] = b[j++];   
        }  
      
        while (i < n)                    //将a中剩下的元素放到C中
            c[k++] = a[i++];  
      
        while (j < m)                  //将b中剩下的元素放到C中
            c[k++] = b[j++];  
    }

    可以看出合并有序数列的效率是比较高的,可以达到O(n)。

      解决了上面的合并有序数列问题,再来看归并排序,其的基本思路就是将数组分成二组A,B,如果这二组组内的数据都是有序的,那么就可以很方便的将这二组数据进行排序。如何让这二组组内数据有序了?

    可以将A,B组各自再分成二组。依次类推,当分出来的小组只有一个数据时,可以认为这个小组组内已经达到了有序,然后再合并相邻的二个小组就可以了。这样通过先递归的分解数列,再合并数列就完成了归并排序。

    //将有二个有序数列a[first...mid]和a[mid...last]合并。  
    void mergearray(int a[], int first, int mid, int last, int temp[])  
    {  
        int i = first, j = mid + 1;  
        int m = mid,   n = last;  
        int k = 0;  
          
        while (i <= m && j <= n)  
        {  
            if (a[i] <= a[j])  
                temp[k++] = a[i++];  
            else  
                temp[k++] = a[j++];  
        }  
          
        while (i <= m)  
            temp[k++] = a[i++];  
          
        while (j <= n)  
            temp[k++] = a[j++];  
          
        for (i = 0; i < k; i++)  
            a[first + i] = temp[i];  
    }  
    void mergesort(int a[], int first, int last, int temp[])   // 递归实现的归并排序(自顶向下)
    {  
        if (first < last)          // 当待排序的序列长度为1时(left == right),递归“开始回升”
        {  
            int mid = (first + last) / 2;  
            mergesort(a, first, mid, temp);    //左边有序  
            mergesort(a, mid + 1, last, temp); //右边有序  
            mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
        }  
    }  
  • 相关阅读:
    HDU5032 Always Cook Mushroom(树状数组&&离线)
    vue proxyTable
    vue-bus 组件通信插件
    gulp 静态资源版本控制
    js运算【按位非】~
    JS 的引用赋值与传值赋值
    手机端取消长按选中
    无刷新URL 更新
    移动端设计稿尺寸(微信端)
    4105: [Thu Summer Camp 2015]平方运算
  • 原文地址:https://www.cnblogs.com/wujing-hubei/p/6129010.html
Copyright © 2020-2023  润新知