Java算法之入门--选择排序与插入排序

        排序,是作为Java算法学习过程中,不可避免的重要知识点。对于大多数的程序员来说,掌握1-2种即可,如最常用的冒泡排序等,本文讲解另外两种排序:选择排序与插入排序。

1,选择排序

       定义:对于长度为N的数组,我们第一次从(0,N-1)找到最小值,将最小值所在位下标同0下标交换,这样确定了首位为最小值,再从(1,N-1)找第二最小值,再交换下标为1的数字,这样确定了第二位位置为第二最小值,依次循环,直到(N-2,N-1)时,该数组已经排好序。

比如给出一个数组Array

int[] Array = {2,1,4,3,5,7}

该数组对应的下标分别表示为 : 0 1 2 3 4 5

选择排序的思路就是,先从下标 0 ~ 5 找最小值,然后与 下标0的数字比较
  
===> 比如Array中,0~5下标区间内,最小值为1,1所在的下标为1,与下标0的数2交换,

Array = {2,1,4,3,5,7} ====> Array = {1,2,4,3,5,7} 

同样的,我们接着进行 从下标 1 ~ 5 找最小值,然后与下标 1 的数字比较

===> 比如Array中,1~5下标区间内,最小值为2,2所在的下标为1,不用交换

继续比较,从下标 2 ~ 5 找最小值,然后与下标 2 的数字比较

===> 比如Array中,2~5下标区间内,最小值为3,3所在的下标为3,要与下标 2 的数字交换

Array = {2,1,4,3,5,7} ====> Array = {1,2,3,4,5,7} 

以此类推,即可达到整个数组按从小到大进行排序

当Array = {1,2,3,4,5,7}时,选择排序完成

了解上述思想后,我们用Java代码实现:

public static void selectSort(int[] arr){
        //  ||--或者  &&--并且  
        //  数组若为空 或 数组 只有一个数字, 则不用排序
        if (arr == null || arr.length<2){ 
            return;
        }
        
        int N = arr.length;
        //0-N-1   1-N-1   2-N-1
        for (int i=0 ;i<N;i++){
            int minValueIndex = i ; 
    for (int j= i+1; j <N ;j++){ //i往后所有数同i比较,如果小则取j,否则取minValueIndex
    minValueIndex = arr[j] <arr[minValueIndex] ? j : minValueIndex ;
            }
      swap(arr,i,minValueIndex); //交换
        }
    }

    //交换
    public static void swap(int []arr , int i , int j){
        int tmp = arr[i];
        arr[j] = arr[i];
        arr[i]= tmp;
    }

2,插入排序

定义:对于一个长度为N的数组,先确定 下标从0-1有序,如果后面的数字比前面的小,则交换,交换后再与前面的数比较,直到前面没有数了,则停止,依次进行0-2,0-3,...,0-N-1上有序。

//比如说对于数组Array

int[] Array = {3,4,1,5,6,2}

对应的下标表示:0 1 2 3 4 5

插入排序的一个思想就是:

先从下标 0 ~ 1 区间内确保有序,也就是说,Array内,0 ~ 1是 3和4,本身有序不用管

再从 0 ~ 2 区间内确保有序,Array内,0 ~ 2是 {3,4,1} 很明显,位于下标3的数比前面的小

所以需要依次交换它的值。这个过程模拟如下:

先下标3的数与下标2的数交换(因为4大于1) 

Array = {3,4,1,5,6,2} ===>  Array = {3,1,4,5,6,2}

此时,下标为2的数字仍然小于前一个数字,因此还要交换 

Array = {3,4,1,5,6,2} ===>  Array = {1,3,4,5,6,2}

这样,就确保了0 ~ 2 区间内有序

依次类推,只要确保 0 ~ N-1 区间内有序时,即
Array = {3,4,1,5,6,2} ===>  Array = {1,2,3,4,5,6}  插入排序完成

了解上述思想后,我们用Java代码实现:

public static void selectSort(int[] arr){
        //  ||--或者  &&--并且
        if (arr == null || arr.length<2){
            return;
        }
       //0-0上有序  0-1  0-2  0-3  0-N-1
        int N = arr.length;
        for (int end= 1;end < N; end++){
            int newNumIndex = end ;
    //左边有数,而且还比我大就要交换
   while (newNumIndex -1 >= 0  && arr[newNumIndex -1] > arr[newNumIndex]){ 
                swap(arr,newNumIndex-1,newNumIndex);
                newNumIndex--;
            }
        }
    }

第一种写法,比较容易理解, 下面给出复杂度更小的写法:

public static void selectSort(int[] arr){
        //  ||--或者  &&--并且
        if (arr == null || arr.length<2){
            return;
        }
       //0-0上有序  0-1  0-2  0-3  0-N-1
        int N = arr.length;
        for (int end= 1;end < N; end++){
           //pre--新数的前一个位置
            for (int pre = end-1;pre >=0 && arr[pre] > arr[pre+1];pre--){
                swap(arr,pre,pre+1);
            }
        }

结尾:冒泡排序,选择排序,插入排序都是比较常用,便于理解的方法。本文中如有错误,欢迎指正! 还请各路大神轻喷!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值