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);
        }
    }
  • 相关阅读:
    metal的gpu query
    体积雾 global fog unity 及改进
    hdr rt format对颜色的影响
    unity deferred lighting
    unity linear space时 photoshop blend的正确设置
    unity linear work flow
    一些数据 bandwidth之类
    deferred rendering with msaa
    unity 显示mipmaplevel
    【转】在C#中使用SendMessage
  • 原文地址:https://www.cnblogs.com/ls-pankong/p/10504792.html
Copyright © 2011-2022 走看看