排序--归并排序

来源:互联网 发布:未闻花名但知花香 编辑:程序博客网 时间:2024/06/05 03:22

归并排序 : 速度仅次于快速排序,为稳定排序算法,一般用于对总体无序,但是各子项相对有序的数列

归并排序的实现大体可分为两步 : 排序 和 归并;

排序的思路:通过递归,把之前无序的大数列逐渐分割成一个个小数列,知道每个数列只含一个数字,此时,各数列有序;

(ps : 通过递归实现就一定要有递归结束的条件 : l == r,到l == r时,被分割开的小的数列里只含一个数字,再不能向下递归,返回上一层,然后又通过递归的到了另一个只含一个数字的数列,然后两数列进行归并

void Msort(int a[], int l, int r){    if (l < r)    {        int mid = (l + r) / 2;        Msort(a, l, mid);        Msort(a, mid + 1, r);        Merge(a, l, mid, r);  //每当两个被分割好的数组进来归并,就用归并好的这两个小数组的数替换原来的数字,纸质全部替换完,归并排序结束    }}
归并的思路 : 一个数组进来后,按照进来的参数l、r、mid,将数列分成两部分(l,mid)和(mid+1,r),然后让这两部分的数字逐个比较,存入另一个中间数组,排序归并完成后,再把中间数组保存的数字重新放到进来的数组相对应位置上,把原来的数值替换掉,实现进来的这一小部分数组的排序。

long long int cnt;      //逆序数可能是个数值很大的数字,用long long int.void Merge(int a[], int l, int mid, int r) //归并:进来一个无序数组(已用mid进行了二分,一直mid、l、r)将进来的分为两部分的数组进行排序,后存入新开的t数组中{    int t[100005];   //int t[] = new int [r - l + 1]申请一个(r - l + 1)个int元素的内存空间,相当于一个n个int元素的数组  int t[r - l + 1]    int i = l, j = mid + 1, k = 0;    while(i <= mid && j <= r)  //中间连接符用的是&&,也就是说重要不符合其中一个条件就跳出循环    {        if (a[i] > a[j])        {            t[k++] = a[j++];            cnt = cnt + (mid - i + 1); //求逆序对数        }        else t[k++] = a[i++];    }    while(i <= mid) t[k++] = a[i++];//跳出循环后,若是在(l,mid)数组内还有未比较到的数字,说明这些数字都大于之前那些比较过的数字,                                      则直接放在数列的后边    while(j <= r) t[k++] = a[j++];    for (k = 0, i = l; i <= r ; k++, i++)        a[i] = t[k]; //将最终排好序的数组再由t重新赋给a数组}
利用归并排序求逆序对数 : 
具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数

原创粉丝点击