归并排序,求逆序数

3 篇文章 0 订阅
package sort;
/*
* @author: wjf
* @version: 2016年4月28日 下午11:01:01
*/

import java.util.ArrayList;
import java.util.Arrays;

public class MergeSort{
    public static int invertedNumber=0;
    public static void mergeSort(int a[],int s,int e){
        // 注意 这里是关键 s=e-1 > s+1=e 即 只有一个元素,此时应该退出,而不是使用s>e 判断
        if(s>=e-1)return;

        int middle=(s+e)/2;
        mergeSort(a,s,middle);
        mergeSort(a,middle,e);
        invertedNumber+=merge(a,s,middle,e);

    }
    public static int merge(int[] a,int s,int middle,int e){
        int tempInverted=0;
        int[] tempa=new int[middle-s];
        int[] tempb=new int[e-middle];
        int counta=0;
        int countb=0;
        for(int i=s;i<middle;i++){
            tempa[counta++]=a[i];
        }
        for(int j=middle;j<e;j++){
            tempb[countb++]=a[j];
        }
        int i=0;
        int j=0;
        int count=s;
        while(i<counta && j <countb){
            if(tempa[i] <= tempb[j]){
                a[count++]=tempa[i++];
            }
            else{
                a[count++]=tempb[j++];
            }
        }
        while(i<counta){
            a[count++]=tempa[i++];
        }
        while(j<countb){
            a[count++]=tempb[j++];
        }
        int m=0;
        for(int k=0;k<counta;k++){
            while(m<countb && tempa[k]>tempb[m]){
                m++;
            }
            // 代码一定要严谨,尤其是 数组下标,m-1 是否越界
            if(m>=1 &&tempa[k] >tempb[m-1] ){
                tempInverted+=m;
            }
        }
        return tempInverted;
    }
    public static void main(String[] args){
        int[] a={5,4,2,3,1,6};
        mergeSort(a, 0, 6);
        for(int i=0;i<6;i++){
            System.out.println(a[i]);
        }
        System.out.println("InverterdNumber is: "+invertedNumber);
//      // 使用了native 实现,效率比较高,是内存复制,省去了大量的数组寻址访问时
//      System.arraycopy(a, 0, b, 2, 6);
//      for(int i=0;i<8;i++){
//          System.out.println(b[i]);
//      }

        /*
         *just test for arrayCopy ,并没有 太大乱用
         */
//      int n=10000000;
//      Integer[] data=new Integer[n];
//      int[] a=new int[n];
//      for(int i=0;i<n;i++){
//          a[i]=i;
//          data[i]=new Integer(i);
//          if(i%10000000 == 0){
//              System.out.println(i);
//          }
//      }
//      try {
//          Thread.sleep(1000);
//      } catch (InterruptedException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
//      System.out.println(n);
////        int[] b=new int[n];
//      int len=100000000;
//      int[] aa=new int[len];
//      int[] bb=new int[len];
//      for(int i=0;i<n;i++){
//          bb[i]=i;
//      }
//      long s=System.currentTimeMillis();
//      for(int i=0;i<n;i++){
//          aa[i]=bb[i];
//      }
//      long e=System.currentTimeMillis();
//      System.out.println(e-s);
//      long e1=System.currentTimeMillis();
//      System.arraycopy(bb, 0, aa, 0, n);
//      long ee=System.currentTimeMillis();
//      System.out.println(ee-e1);
//      ArrayList<Integer> list=null;
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值