前言
SSM企业级应用开发学完后,做过一些小项目,算是有点小项目经验,但是基本上都是基于框架开发,基础涉及到了,但是没有深究原理,所以学完SSM之后想根据大纲复习复习以前忘掉的基础。看到数组这块的时候有提到找到最值,遂想起冒泡排序,故重新实现了一次,不过过程却是异常艰难,因为我基本上都忘了,哈哈哈。所以这次花费一个多小时重新写算法,重新理清思路,重新认识其中的每一步,更重要的是,这次纯手写,无copy。
OK,开始正文…
package test;
public class arrayTest {
public static void main(String[] args) {
int[] arr ={2,1,61,24,0,9,415,29,44,16};
// 1,2,24,0,9,61,29,44,16,415
for (int a:arr
) {
System.out.print(a+"\t");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
System.out.println();
//冒泡排序
//因为每次都能选出一个最大或者最小的数字,所以最多需要循环执行数组长度-1次就可完成排序
for (int i = 0; i < arr.length; i++) {
//此处为什么要-1,因为下面代码中有涉及到当前元素的下一个元素,所以如果不给j-1则会超出数组边界
//此处为什么要-i,因为i每+1就少一个数字需要被排序,所以只需要排序数组长度-1-i次就可完本次排序
for (int j = 0; j < arr.length-1-i; j++) {
int lit = arr[j];
int big = arr[j+1];
int mid;
if ( big < lit ){
mid = lit;
lit = big;
big = mid;
arr[j] = lit;
arr[j+1] = big;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+"\t");
}
}
}
变量命名和代码还可以继续优化,这里只是为了方便看懂流程而一步一步走下来
从冒泡排序开始,第二层for循环的代码每次执行均可筛选出一位最大或者最小数,这是基础,因为你整个数组有多少个元素,就要挑选出多少个最值,所以引出了第一层for循环用来控制整体的循环次数。
细则开始
-
为什么第二层for循环可以筛选出一个最值呢?
第二层for循环中的代码,有三个变量,分别是:
---------变量名 | 含义 |
---|---|
lit | 全名little,意思为小的,我在这的用意是用来表示:这个变量值在此处***应当***是最小的 |
mid | 全名middle,意思为中间,我创建这个变量的用意是方便用来零时存放lit或者big的值,以用来交换lit和mid的值 |
big | 这个名字很简单,就是意思为大的,用意是表示:这个变量值在此处***应当***是最大的 |
以升序排列为例,当右边的元素小于左边的元素时,那么就会执行这段代码:
if ( big < lit ){
mid = lit;
lit = big;
big = mid;
arr[j] = lit;
arr[j+1] = big;
}
这段代码会按照arr[1]和arr[2]比比较,arr[2]和arr[3]比较,······,所以每次第二层for循环都会选择出一个最值,放在数组的末尾。
-
为什么第二层for循环中有个条件为“j < arr.length-1-i”,其中的“i”和1表示什么?
-
“j < arr.length-1-i”这个条件是用来整体控制筛选代码筛选多少次会取出一个最值。
-
-1这个条件是为了避免出现数组下标越界,也就是超出数组边界。
-
-i这个条件则主要是用来优化流程提高性能的(所以说这个-i亲测可以删掉,虽然这玩意暂时没啥可提升性能的,嘿嘿)
因为前面说过,第一层for循环每执行完一次说明第二层for循环已筛选出一个最值,所以,为了提高效率,我们可以少比较i个数组元素。因为第一次筛选最值的时候是所有元素都经历过比较而筛选出来的,也就是说第一次筛选会筛选出整个数组中最大的元素放在最数组最后面,而接下来的每次筛选可以安全的放弃与最大的元素比较且不影响排序结果。
-