java中的排序算法——归并排序

为什么使用归并排序? 

java中的Arrays.sort(Object[] o)是对数组进行排序,它使用的是归并排序的方式, 
快速排序要比归并排序更快一些,但为什么使用归并排序了?原因是归并排序是一种稳定的排序 
方式,即归并排序不交换相同的元素,这就意味着,在按一种方式排序后同时可以按另外一种 
方式进行排序。比如员工可以首先按工资排序,然后按名字排序,一种排序不会打乱另一种排序 
的顺序。 
下面分析下sort方法的简化版:
    /**
     * 归并排序 (递归实现)
     * 前提: 每个元素要有可比性,这里元素必须实现Comparable接口。
     * 基本原理为:1.拆分 假设有N个元素的列表,首先把它拆分成2个或2个
     * 以上的元素组成的新的列表(这里我的新列表长度不超过3),分别对对它们进行排序。
     * 2.归并。把所有的排好序的子类表两两归并,如此重复,直到归并成一个含N个
     * 元素的有序列表为止
     * 图解:(大于3就继续分解)
     *  大于3          8    7    6    5     4     3     2     1
     *                                分|解
     *                                  |
     *  大于3            8  7  6  5            4   3   2   1 
     *                     分|解                  分|解
     *                       |                      | 
     *  小于 3            8 7   6 5             4  3    2 1
     *  排序              7 8   5 6             3  4    1 2 
     *  归并                 |                       | 
     *                  7   8  5  6            3  4    1  2 
     *                       |                       |
     *  顺序保存        5   6  7  8            1  2    3  4
     *                                   |
     *  归并           5    6    7    8   1    2    3     4
     *   |
     *  顺序保存       1    2    3    4   5    6    7     8
     * @param src 临时中间数组,它是目标数组的拷贝
     * @param target 目标排序数组
     * @param low 需排序的起始索引
     * @param high 需排序的结束索引
     * 
     */
    public static void mergeSort(Object[] src,Object[] dest,int low,int high){
    int length = high - low;
    if(length < 3 ){ //对长度小于3的列表排序
    //排序方法一:起泡排序(大数沉底)
//     for(int i=low;i<high-1;i++){
//     for(int j=low;j<high-1-i+low;j++){
//     if(((Comparable) dest[j]).compareTo(dest[j+1]) > 0){
//         swap(dest, j, j+1); 
//         }
//     }
//     }
    //排序方法二:这是起泡排序的一种变体(小数上浮)
    for (int i = low; i < high; i++){
    for (int j = i; j > low ; j--){
    if(((Comparable) dest[j - 1]).compareTo(dest[j]) > 0){
    swap(dest, j-1, j); 
    }
    }
    }
    return;
    }
   
    int mid = (high + low)/2; //拆分
    mergeSort(dest, src, low, mid); //递归,可能会继续拆分(那么必然继续合并)
    mergeSort(dest, src, mid, high);
   
    //开始归并,方法一
//     for(int i=low,p=low,q=mid;i<high;i++){
//     //第一个条件时为了添加剩余的值
// if(q >= high || (p < mid &&((Comparable) src[p]).compareTo(src[q]) <= 0)){
// dest[i] = src[p++];
// }else{
// dest[i] = src[q++];
// }
//     }
   
    //开始归并,方法二
    int i = low;
    int p = low; //第一个列表指针
    int q = mid;    //第二个列表指针
    while(p < mid && q <high){
    if(((Comparable) src[p]).compareTo(src[q]) <= 0){
    dest[i++] = src[p++];
    }else{
    dest[i++] = src[q++];
    }
    }
    //添加剩余的值
    while(p < mid && i<high){
    dest[i++] = src[p++];
    }
    while(q < high && i<high){
    dest[i++] = src[q++];
    }


    private static void swap(Object[] x, int a, int b) {
    Object t = x[a];
    x[a] = x[b];
    x[b] = t;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值