冒泡排序,选择排序和插入排序

这两天的《算法》进入排序的学习后,遇到了一些问题,下面是我自己总结的理解:


冒泡排序:
两两相比较遍历数组不断以两两交换的方式找到最值(最大或最小),再从循环中剔除该最值缩小遍历范围继续一次从头至尾的遍历,循环很多次至最终排序完成。

选择排序:
以一个变量存储下表索引,同冒泡排序一样的两两相比较,但不交换,而是不断用变量存储极值(大或小)的索引,直至找到最值后与边界元素外循环a.[i]交换,然后i自增剔除该最值缩小遍历范围继续用该方法遍历,循环很多次至最终排序完成。

插入排序:
以一个数组元素为标志(算法中一般从边界开始),以一个方向依次为反方向的相邻元素相比较,若比较结果符合排序要求,则该标志前进(外循环自增一),继续按照方向与下一个进行比较;若结果不符合排序要求,则进入内循环,找出的这个不符元素与相邻元素交换后退,然后继续后退与相邻元素比较(再交换),直至后退至该元素的位置符合排序要求,然后退出内循环,外循环自增一标志继续前进。这样的外循环一次遍历之后,排序完成。如果数组本身是部分有序的,那么排序时间将大大减少。

总结:
选择排序是冒泡排序的优化,虽然两种比较次数是一样的,但是选择排序减少了交换次数,缩减了排序时间

插入排序相比上述排序,以精妙的算法极大优化了比较次数,因此在《算法》p160中定论:插入排序平均比选择排序快一倍。但这并不是插入排序的最优解,在书中p158中有提到,因为内循环中,找到不符元素后,采用了冒泡排序的思想不断交换,可以进一步进行优化,把比待插入值大的值均向后移动以为而不是操作待差值两两交换,最后存在两个相同的值,该值是比待差值大的最接近的值,将待差值与上述值原位置值变为待差值完成插入,就能进一步缩减排序时间,如下:

交换式:

    public static void insertSort(int[] arr) {
        int insertVal = 0;
        int insertIndex = 0;
        int temp=0;
        //使用for 循环来把代码简化
        for(int i = 1; i < arr.length; i++) {
            //定义待插入的数
            insertVal = arr[i];
            insertIndex = i - 1; // 即arr[1]的前面这个数的下标
            
            // 给insertVal 找到插入的位置并交换
            for(int j=insertIndex;j >= 0;j--){
                if (insertVal < arr[j]) {
                    temp = arr[j];
                    arr[j]=arr[j + 1];
                    arr[j + 1]=temp;
                }
            }

            System.out.println("第"+i+"轮插入");
            System.out.println(Arrays.toString(arr));
        }
    }

移位式:

public static void insertSort(int[] arr) {
int insertVal = 0;
int insertIndex = 0;

//使用for 循环来把代码简化
for(int i = 1; i < arr.length; i++) {
    //定义待插入的数
    insertVal = arr[i];
    insertIndex = i - 1; // 即arr[1]的前面这个数的下标

    // 给insertVal 找到插入的位置
    while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
        arr[insertIndex + 1] = arr[insertIndex];// arr[insertIndex]
        insertIndex--;
    }

    //这里我们判断是否需要赋值
    if(insertIndex + 1 != i) {
        arr[insertIndex + 1] = insertVal;
    }
    System.out.println("第"+i+"轮插入");
    System.out.println(Arrays.toString(arr));
}
}

 


上述三种算法都无法解决大型数组问题,或者性能很差

以上排序的源码百度一下到处都有,注意理解对应就好

posted @ 2020-09-25 15:12  Jancy丶  阅读(206)  评论(0)    收藏  举报