冒泡排序
在讲到冒泡排序之前,我希望你能真正理解循环,循环到底是什么?循环到底是在我们做事的哪些环节帮助了我们?只有真正理解了循环,才能让我们在使用它的时候游刃有余。
我们最直观的理解就是,让机器重复的干一件事,因此,我们最常干的事情就是把一件事情放在for或者while循环体之中,但如果我们只是简单地把执行循环理解到这种程度,那么,我们在接触到双重循环或者多重循环的时候就会很难在公式化的教学中,萌生出自己的想法和灵感。在此,我将用庖丁解牛的方式,把循环的逻辑剖析出来。
首先,我们在循环体中,可以分为两个部分———循环关键词、执行事件。我们重点应该关注的是执行事件,这个事件到底在干什么,举个例子
int[] arr = new int[5];
for(int i = 0; i < arr.length; i++){
System.out.print(arr[i] + "\t");
}
这个程序中大家很熟悉——打印出数组中的元素。那么在这个程序中,循环关键词是”for“,执行事件是”打印“,至此,你已经了解了到这个程序要干什么,也就是重复做出”打印“这个行为,我们最初设计这串代码不需要考虑他到底每次要怎么变化,”i“是干什么的,”i++“是干什么的。我最初的想法就是——让电脑重复的做”打印“这个动作。举个例子,当一个工厂有很多货物的时候,我们需要的是一位搬运工人,我们一直希望他做的是把货物从a搬到b,我们先不考虑让他搬什么货物,先搬哪个后搬哪个,所以循环的本质,是对一个或者多个行为的重复。如果大家都以这种方式去初步思考,我相信,你很快就能有兴趣把你”cv大法“得到的那些代码理解下去。
现在你知道循环的本质是什么,那么我们来理解一下冒泡排序。
我们首先得到几个数字——”10,2,15,36,1,9“,并希望可以通过计算机把这些数字按照从小到大或者从大到小排序,当然我们人类可以一眼把六位数排序起来,这得益于我们常年对数字的感觉,通过大脑中我不知道的某些神经元的交互让我们做出的选择,甚至这种感觉有时候自己也说不清道不明,因此我认为,对于这种感觉的依赖,会影响到我们对程式化的理解。所以在我们设计循环之前,让自己先暂时摒弃这种感觉吧,让我们带入这个没有任何感情的机器里面去,当我们面对这六位数的时候,我们根本不知道怎么排序,就像站在六座仅彼此相差几厘米高度的大厦面前,将他们排高度一样,我们能做的就是在两个大厦之间得知他们两个谁高,因此,我们该怎么做呢?
那我们来看冒泡算法是怎么做的,如果我们希望最高的楼在最右边,那么我们首先给楼编好序号,这里我们用”1号,2号,……6号“,冒泡排序希望我们先拿1号和2号作比较,如果1号比2号高,那么他们做交换,这时候原先的1号成了现在的2号,原先的2号现在变成了1号。这时候,一个完整的动作完成了——”比较后交换“。如果你没看懂,我希望你再重新读一遍这段话,因为现在我们还没涉及到算法,只是在解释这个动作在做什么。那么我们重复这个动作,把2号和3号做对比,如果2号比3号低,那么我们什么都不做,继续重复我们的动作,把3号和4号做对比,这时候我们发现,高楼一直往右走,直到重复到最后一步,我们就成功的把最高得楼排在了最右边。如果你没有理解为什么,那么你这样极端地去想,如果第一个楼就是最高楼,那么他在每次对比的时候都要交换,因此他会一步一步向右走,直到楼号变成6号。因此,我们已经完成了”比较后交换“的最后一步,但我们只是把最高楼排好了,所以我们在排序上,也只是做了第一步。当我们理解了”比较后交换“这个动作后,我们发现,以后不管怎么换,最高的楼也不可能会被换走。所以我们再来一次,从1号楼开始,再重复一遍,这时候要注意,这时候的楼号是我们第一轮交换后的结果,不要被最初的楼号所影响,还记得吗,最初的1号成了现在的2号,2号成了1号。当我们做到这一轮的最后一步时,第二高的楼排到了5号,这时候,5号和6号就永远不会动了。当你看懂到现在的时候,恭喜你,你已经理解了冒泡排序,我们只需要一遍一遍的去重复,最后我们会发现,每个楼相互对比都不会交换,这时候就已经排好了。
那么我们看看代码是怎么实现的:
int[] arr = {10, 2, 15, 36, 1, 9};
int tem;
for (int i = 0; i < arr.length; i++) { /*这个for循环里面的执行事件是“重复下一个for循环”,也就是我们上面说过的, “再从1号楼过一遍”,也可以说是大循环,那么我们要做多少次呢,我们发现每执行一次,就会有一个高楼固定在排行榜的名次上,那么需要对比的楼的数量就会减1,所以我们有几个数就做几次大循环*/
for (int j = 0; j < (arr.length - 1); j++) { /*这个for循环中的执行事件是“对比后交换”*/
if (arr[j] > arr[j + 1]){
tem = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tem;
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + "\t");
}
好了,至此,我们已经掌握了冒泡排序的原理和实现方式。
本人比较笨,学习编程的时候处处碰壁,多次被劝退,在此希望通过连我都能理解的方式给大家带来哪怕一点帮助,顺便给自己当笔记,防止日后再绕不过来。如文中有不当之处,希望各位帮我指出,我虚心学习,这是我的第一篇文章,以后会不定期更新