zoukankan      html  css  js  c++  java
  • 归并排序&&归并排序求逆序对

    归并排序

    归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

    算法:

    第一步:申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列
    第二步:设定两个指针,最初位置分别为两个已经排序序列的起始位置
    第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
    重复步骤3直到某一指针超出序列尾
    将另一序列剩下的所有元素直接复制到合并序列尾
     
    
    import java.util.*;
    
    public class Main1 {
        static int a[] = new int[10010];
        static int b[] = new int[10010];
         
    
        public static void sort(int a[], int l, int r) {
            if (r - l > 0) {
                int mid = (r + l) / 2;
                int i = l;
                int p = l;
                int q = mid + 1;
                sort(a, l, mid);
                sort(a, mid + 1, r);
                while (p <= mid || q <= r) {                  
                    if (q > r || (p <= mid && a[p] <= a[q]))      //这一点是简化代码,包含了当后边数组没有比前一半大的时候
                        b[i++] = a[p++];
                    else {
                        b[i++] = a[q++];
                         
                    }
                }
                for (i = l; i <= r; i++)
                    a[i] = b[i];
            }
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            for (int i = 1; i <= n; i++) {
                a[i] = sc.nextInt();
            }
            sort(a, 1, n);
            for (int i = 1; i <= n; i++)
                System.out.printf("%d ", a[i]);
            System.out.println(ans);
        }
    }

    归并排序求逆序对

    求序列的逆序对,先看下面的例子:

    设有数列{6,202,100,301,38,8,1}

    初始状态:6,202,100,301,38,8,1

    第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;

    第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;

    第三次归并后:{1,6,8,38,100,202,301},比较次数:4;

    总的比较次数为:3+4+4=11;

    逆序数为14;
     

    根据归并排序的特性(左右两部分的有序序列合并时,假设i在左边,j在右边,对于右边的j,统计左边比它大的元素个数s(j),则s(j) = mid-i+1 ,合并万所有的序列时即可得出答案,即f(j)之和便是答案),只需将上面的代码修改一处:把“else  b[i++] = a[q++];”改成“ else {b[i++] = a[q++];  ans += mid-p+1;}" ,注意在调用之前将ans清零。
     

    package demo2;
    
    import java.util.*;
    
    public class Main1 {
        static int a[] = new int[10010];
        static int b[] = new int[10010];
        static int ans = 0;
    
        public static void sort(int a[], int l, int r) {
            if (r - l > 0) {
                int mid = (r + l) / 2;
                int i = l;
                int p = l;
                int q = mid + 1;
                sort(a, l, mid);
                sort(a, mid + 1, r);
                while (p <= mid || q <= r) {
                    if (q > r || (p <= mid && a[p] <= a[q]))
                        b[i++] = a[p++];
                    else {
                        b[i++] = a[q++];
                        ans += mid - p + 1;
                    }
                }
                for (i = l; i <= r; i++)
                    a[i] = b[i];
            }
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            for (int i = 1; i <= n; i++) {
                a[i] = sc.nextInt();
            }
            sort(a, 1, n);
            for (int i = 1; i <= n; i++)
                System.out.printf("%d ", a[i]);
            System.out.println(ans);
        }
    }
  • 相关阅读:
    例程 | 串口助手Comm Assist
    教程 | 蓝牙设备查找类CxBthRadio & CxBthRadioFind
    教程 | 服务端套接字类CxServerSocket
    openlayers 3加载GeoServer发布的wfs类型服务
    Geoserver端口冲突解决方案(二)
    Geoserver端口冲突解决方案
    GeoServer基础教程(四):空间数据互操作的接口规范WMS、WFS和WCS
    GeoServer基础教程(三):部署发布Shapefile地图数据
    GeoServer基础教程(二):GeoServer的Web管理界面快速入门
    GeoServer基础教程(一):环境搭建篇
  • 原文地址:https://www.cnblogs.com/ls-pankong/p/10504792.html
Copyright © 2011-2022 走看看