JavaSE——七大排序 上篇

7大基于比较的排序:插入排序|希尔排序、选择排序|堆排序、冒泡排序、快速排序、归并排序

**注意

1.排序:默认情况都是按非降序排序(In-place 原地排序)

2.稳定的排序:具有稳定性(即能保证排序过程中相等的数据的相对顺序不变)。

3.插入排序:(减治算法排序)

每次从无序区间选择第一个数,插入到有序区间的合适位置,直到全部有序。

有序区间

无序区间

//法一:
public static void insertSort(int[]array){
    for(int i =0; i<array.lenghth-1;i++){
        //有序区间:[0,i]  无序区间[i+1,array.lenghth]
        //待插入的数据是:array[i+1]
        //插入过程在有序区间进行查找
        int key = array[i+1];
        int j;
        for(j=i;j >= 0 && key < array[j];j--){
            array[j+1] = array[j];
        }
        array[j+1] = key;
    }
 }   
//法二:
public static void insertSort1(int[] array){
    for(int i=0;i<array.length-1;i++){
        int key = array[i+1];
        int j;
        for(j= i;j>=0;j--){
           if(key >= array[j]){
            break;
            }
            //j+1 放 key 的位置
            for(int k = i;k >j;k--){
                array[j+1] = key; 
            }
        }
    }      
}

*3.1思路:如果有n个数,则外层循环需循环n-1次

(1)**查找:从后往前找

(2)**插入:每次都把无序区间的第一个数,在有序区间内遍历(从后往前遍历)

1.一共需要进行多少次插入? size-1(size次也可以)

2.找到合适的位置,搬移原有数据,为该数据腾出位置。

3.2时间复杂度:

最好

平均

最坏

O(n) 完全有序(从后往前比较)

O(n^2)

O(n^2)

3.3空间复杂度:O(1)

3.4稳定性:稳定

3.5 总结:插入排序,越接近有序,执行时间效率越高

3.6 计时:

long begin = System.nanoTime(); //纳秒(打印前计时)
long end = System.nanoTime();  //纳秒 (打印后计时)
System.out.println(end -begin);     //打印排序所需时间

4.希尔排序(Shell Sort)

前提:利用插入排序中,数据越接近有序,时间效率越高

在插入排序之前做预排序(分组插排),使数据尽可能地接近有序

//定义gap进行分组排序   和插入排序相似
private static void insertSortWithGap(int[]array,int gap){
    for(int i = 0;i <array.length - gap;i++){
        int key = array[i+gap];
        int j;
        for(j = i;j>= 0 && key <array[j];j-=gap){
            array[j+gap] = array[j];
        }
        array[j+gap] key;
    }
}
public static void shellSort(int[]array){
    int gap = array.length;
    while(true){
        gap = gap/3+1;
        insertSortWithGap(array,gap); //调用insertSortWithGap
        if(gap == 1){
            return;
        }
    }
}

 先处理每组的第一个数,在处理每组的下一个数。

 

第一组

第二组

第三组

第四组

    

4.1如何分组的问题:

分组分的很多:可以很快走到最后去

分组分的很多:每次分组排序后,数据接近有序

动态分组:一开始分很多组,越来越少

4.2时间复杂度

最好

平均

最坏

O(n)

O(n^1.3-1.4)

O(n^2)

4.3 空间复杂度 O(1)

4.4 稳定性:不稳定(相等的两个数被分到了两个不同组,无法保证)

4.5 插入排序:直接插入排序(掌握)、折半插入排序(了解)

5.选择排序(直接选择排序/堆排序)------减治算法

思想:每次遍历无序区间(直接遍历/利用堆),找到无序区间的最大的数,把最大的数放到无序区间的最右边。一直选择n-1或n数之后,数据完全有序。

区别:直接选择排序是通过遍历来找无序区间的最大值;堆排序是通过建大堆来找无序区间的最大值

5.1直接选择排序(遍历选最大值)

public static void selectSort(int[] array){
    //每次选最大的数(循环n-1次)
    for(int i=0;i<array.length-1;i++){
            //无序区间[0,array.length-i)      
            //有序区间[array.length-i,array.length]
       int max = 0;
       for(j=1;j<array.length-i;j++){
           if(array[j]>= array[max]){
               max = j;
           }
       }  
       //交换最大的数和无序区间的最后一个数
        swap(array,max,array.length-i-1);  
    }
}  
private static void swap(int[] array,int i,int j){
    int t = array[i];
    array[i] = array[j];
    array[j] = t;
}      

时间复杂度 :O(n^2) 数据不敏感

空间复杂度:O(1)

稳定性:不稳定(看经过改造是否能具有稳定性) 例如:9 5 2 3 5

5.2堆排序(选最大的数)

思想:首先将现有的元素建大堆,,然后将最大元素和最后的元素交换,在堆中去除最后一个元素,一直循环下去。

时间复杂度:O(n*log(n)) 数据不敏感

空间复杂度:O(1)

稳定性:不稳定

**选择排序选最大的,选最小的可以吗?

(1)选择排序可以同时选最大+最小,最大的往后换,最小的往前换。

(2)堆排往往建大堆,小堆更复杂,效率更低。

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值