DS_【归并排序】

Java-四大排序

  • 归并排序

归并的实现排序的一种解决方式,该算法直接体现分 和 治

归并排序过程描述

  1. 准备一个承载的数组该数组的长度与待排序的数组大小相同
  2. 排序的过程从小到大 先分组后排序
  1. 先把所有的数据两两分组 i=1  s1=0 e1=0 s2=1 e2=1 使用s1--e1 表示分组排的第一个数组s2---e2表示分组排的第二个 经过第一次 数组A 和数组 B中存放 arra[0] arr[1]

通过比较A与B中的元素在temArray按序排列

然后一起拿到下两个组放入A B 中进行同样的比较

经过第一次的分与治每个数字两两分组排列排序后的返回array中

  1. 第二次 i=2   s1=0 e2=1 s2=2 e3=3传入记为A B

对A B两个安排数组进行比较

  1. Array[s1]<Array[s2]  array[s1]先存入tmpArray  s1++ s1=1

  1. Array[s1]>Array[s2]  array[s2]存入tmpArray  s2++ s2=3

再重复(1)(2)

再传下下两个组

经过第二次 tmpArray 4 5 7 8 1 2 3 6

 

  1. 第三次i=4 传入 A s1=0 s2=3 Bs1=4 e2=7

非递归算法过程描述

i表示分组大小

  1. i=1 s1-e1 s2-e2 每个组一个元素 循环遍历两个组归并两个组
  2. i=2 每组2个元素
  3. i=4
  4. i=8
  5. 在比较时候 s1=0 e1=s1+gap(i)-1  s2=e1+1 e2=s2+gap(i)-1

两个组比较时while(start1<=end1&&start2<=end2){
    if(array[start1]<=array[start2]){
        tmpArray[i++] = array[start1++];
    }else{
        tmpArray[i++] = array[start2++];
    }
}
while(start1<=end1){
    tmpArray[i++] = array[start1++];
}
while(start2<=end2){
    tmpArray[i++] = array[start2++];
}

(6)比较完成后start1 = end2+1;
end1 = start1+gap-1;
start2 = end1+1;
end2 = start2+gap-1>array.length-1?array.length-1:start2+gap-1;

代码实现

```javascript

public static void mergeSort_Un(int[] array){
    long start = System.nanoTime();
    for(int i=1;i<=array.length;i=2*i){
        merge(array,i);
    }
    long end = System.nanoTime();
    System.out.println("非递归归并排序时间"+(end-start)+"纳秒");
}
public static void merge(int[] array,int gap){
    int[] tmpArray = new int[array.length];
    int i=0;  //tmpArray 的下标
    int start1 = 0;
    int end1 = start1+gap-1;
    int start2 = end1+1;
    int end2 = start2+gap-1>array.length-1?
            array.length-1:start2+gap-1;
    //保证有两个段
    while(start2<array.length){
        //两个归并段 在归并中 都要有数据
        while(start1<=end1&&start2<=end2){
            if(array[start1]<=array[start2]){
                tmpArray[i++] = array[start1++];
            }else{
                tmpArray[i++] = array[start2++];
            }
        }
        while(start1<=end1){
            tmpArray[i++] = array[start1++];
        }
        while(start2<=end2){
            tmpArray[i++] = array[start2++];
        }
        start1 = end2+1;
        end1 = start1+gap-1;
        start2 = end1+1;
        end2 = start2+gap-1>array.length-1?array.length-1:start2+gap-1;
    }
    while(start1<=array.length-1){       //start1<=end1 加入最后一个数组 只有一个值 就会发生数组越界
        tmpArray[i++] = array[start1++];
    }
    for (int j = 0; j < tmpArray.length; j++) {
        array[j] = tmpArray[j];
    }
}

```

时间

**********有序**********

非递归归并排序时间16557778纳秒

**********无序**********

非递归归并排序时间5777纳秒

递归实现归并算法

思路

  1. 通过 mid拿到一个组的中间下标
  2. mergeSort函数依次递归左边和右边
  1. mergeSort通过不断的调用自身继续分化
  1. 当所有的组分为只有一个元素时
  1. 然后不断地比较相邻的两个组的元素合并
  1. 实现成体排序

将所有的数据分分为若干组魅族的元素个数唯一

在进行合并时保证每一个组在合并时都有序

代码实现

```javascript

public static void merge(int[] array){
    long s1 = System.nanoTime();
    mergeSort(array,0,array.length-1);
    long s2 = System.nanoTime();
    System.out.println("归并排序递归时间"+(s2-s1)+"纳秒");
}
public static void mergeSort(int[] array,int start,int end){
    if(start>=end){
        return ;
    }
    int mid = (start+end)>>>1;          //找到 中间
    mergeSort(array,start,mid);         //递归排序左边
    mergeSort(array,mid+1,end);
    //合并函数
    mergeMethod(array,start,mid,end);
}
public static void mergeMethod(int[] array,int start,int mid,int end){
    int[] tmpArr = new int[array.length];
    int tmpIndex = start; //存放 tmpArr下标
    int start2 = mid+1;   //第二次归并 start
    int i = start;
    while(start<=mid&&start2<=end) {          //进入 归并过程
        if (array[start] <= array[start2]) {        //如果 array[start] 小于 s2 将两个之中的小值 存入新建数组中
            //新建数组与栈类似 又有 tmpIndex 表示 存放的下标
            tmpArr[tmpIndex++] = array[start++];  //那个值小 存那个
        } else {
            tmpArr[tmpIndex++] = array[start2++];
        }
    }
        while(start<=mid){
            tmpArr[tmpIndex++] = array[start++];
        }
        while(start2<=end){
            tmpArr[tmpIndex++] = array[start2++];
        }
    while(i<=end){
        array[i] = tmpArr[i];
        i++;
    }
}

 

```

时间

**********有序**********

归并排序递归时间5453525777纳秒

**********无序**********

归并排序递归时间5756729333纳秒

总结

  1. 归并排序在实现时采用先分后合的思想性能优,比较类似于二叉树
  2. 空间复杂度 O(N) 每一次排序时都要申请开辟空间tmpArray
  3. 时间复杂度O(N*logN)
  4. 稳定性 稳定 不存在交换

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值