[钻研Java算法:不断完善中]

钻研Java算法

此处输入图片的描述

Java算法导论


选择排序 : 每一轮比较排序会产生一个最值,然后根据当前最值进行下一轮比较排序, 比较完成的最值不参与之后的比较排序!


冒泡排序 : 也万变不离其宗,但有些区别 , 冒泡排序每轮也会生一个最值 , 但不根据当前最值进行下一轮比较排序 , 依然是第1个和第2个数 ,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至冒泡排序完成,每轮产生的最值同样不参与之后的比较排序!

总结ing ,如果需要排序性能最优,减少在堆内存中交换位置的次数,在栈内存中进行临时 param.length-i-1 存储比较~

1.排序算法之简单选择排序(Selection sort)

[ 简单选择排序基本思想 ]

在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。

[ 简单选择排序的可视化示例 ] :

红色 : 以排序完成的元素

灰色 : 未排序完成的元素

浅蓝 : 将第一位灰色元素和其他未排序元素一一进行排序规则比较比较找出深蓝元素

深蓝 : 本次扫描符合排序规则的元素, 下次扫描前与红色元素后的灰色元素交互位置


[ 简单选择排序的数值变化示例 ] :

此处输入图片的描述

[ 简单选择排序的代码示例 ] :

此处输入图片的描述

/**
     * Java排序算法/选择排序
     *
     * @param param []
     * @return   嵌套多层for循环排序的特点, 内循环可以依赖于外循环进行计算,
     * 但外循环不能依赖内循环进行计算,每次运行一次外循环都会重新初始化内循环,
     * 然后将内循环运行跑完,再运行外循环!
     */

    public static int[] selectSort(int param[]) {
        //param.length-1 : 是外循环圈数 -1 ,剩下最后一个最值元素不用再走一遍循环比较,性能最优!
        // 第一周i的值为0,第二周为1,第三周为2
        // 外循环中 i 在初始化时为0 ,第一次外圈为1,第二次外圈为2
        for (int i = 0; i < param.length - 1; i++) {
            // int j = i+1 : 每次循环到内循环时,j的值= i+1, j索引 永远指向 i后一位元素 !
            // 第一周j的值为1,第二周为2,第三周为3,在单次内循环中i值不变为0,j值每圈会自增++
            for (int j = i + 1 ; j < param.length; j++) {
                // 比较获取最小的值 ,每次内循环中i变量值不变,j值在i值上+1.为了防止自己与自己比较,性能最优!
                // 单次内循环中 j 值多次自增,将i索引上的值与j 索引的值进行比较,如果小就走if逻辑
                if (param[i] > param[j]) {
                    // 用temp变量记录 param[i] 索引位上的值,方便交换赋值
                    int temp = param[i];
                    param[i] = param[j];
                    param[j] = temp;

                }
            }
        }
        return param;
    }

[ 简单选择排序的代码Debug示例 ] :

此处输入图片的描述

2.排序算法之冒泡排序(Bubble sort)

[ 冒泡排序基本思想 ]

依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。重复第一趟步骤,直至全部排序完成,

举个栗子:有一个元素个数为5的一维数组 [3,1,54,2,7] ,用冒泡算法对数组排序~

第一轮冒泡排序 :

第一位数 3比1大 交换位置后得 结果集[1,3,54,2,7]
第二位数 3比54小 不交换位置得 结果集[1,3,54,2,7]
第三位数 54比2大 交换位置后得 结果集[1,3,2,54,7]
第四位数 54比7大 交换位置后得 结果集[1,3,2,7,54]

第一排序结束 , 产生最值 54 , 最值不进行下次比较排序!


第二轮冒泡排序 :

第二轮冒泡排序 :

第一位数 1比3小 不交换位置得 结果集[1,3,2,7,54]
第二位数 3比2大 交换位置后得 结果集[1,2,3,7,54]
第三位数 3比7小 不交换位置得 结果集[1,2,3,7,54]

第二排序结束 , 产生最值 7 , 最值不进行下次比较排序!

小数逐渐浮出水面,大数逐渐往下沉底,这就叫冒泡排序!

[ 冒泡排序的可视化示例 ] :
推荐可视化示例视频 ( 0.5倍播放 ) : https://v.qq.com/x/page/c0506yg8yfa.html

此处输入图片的描述

[ 冒泡排序的数值变化示例 ] :

此处输入图片的描述

[ 冒泡排序的代码示例 ] :

此处输入图片的描述

public static int[] bubbleSort(int[] param) {
        // Test数组 int[] params = {42, 3, 1, 2, 7, 8, 10};

        //param.length-1 : 是外循环圈数 -1 ,剩下最后一个最值元素不用再走一遍循环比较,性能最优!
        for (int i = 0; i < param.length - 1; i++) {

            //param.length-i : 每轮产生一个最值,每轮比较次数依次递减1,不比较已产生的最值元素 !
            // param.length-i-1 : 避免索引发生越界!
            //例: 在第一圈时 i = 0  , param.length - i(0) = 7 , j 索引自增到7 抛出 ArrayIndexOutOfBoundsException !

            // 每轮遍历元素个数递减-1 次,逐轮产生1个最值不进行下次比较!
            // 逐轮打印j 的值的为: 0 1 2 3 4 5| 0 1 2 3 4| 0 1 2 3| 0 1 2| 0|

            for (int j = 0; j < param.length - i - 1; j++) {

                //这个 [j] 就相当于 0 ,[j + 1] 就相当于 1 !
                // 然后将两个索引上的元素进行比较将小数放前,大数放后!
                //下一轮 [j] = 1 ,[j + 1] = 2 进行比较将小数放前 !
                if (param[j] > param[j + 1]) {
                    //swap过程中不用i索引进行比较,用j和j+1进行比较,将小数放前,大数放后 !
                    int temp = param[j];
                    param[j] = param[j + 1];
                    param[j + 1] = temp;
                }
            }
        }
        return param;
    }

[ 冒泡排序的代码Debug示例 ] :

此处输入图片的描述

发布了29 篇原创文章 · 获赞 9 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_37977176/article/details/79474986