作为一个没有任何编程基础的人来说,新学一门编程语言是一件比较困难的事情。
语法和思维方式的转变是一个难点,但也还好。最困难的地方,是因为不常使用而导致的遗忘。
因此决定每每学到什么新东西,在这里记录下来,以便以后常读常新。今天写的便是昨晚看到的冒泡排序。
假设这里有一个数组,现在要将这个数组从大到小排列起来。
int[] sr = {12,43,23,65,41,54,32,3,56,22};
思路:将数组中相邻两个数进行比较,将较大的数放到左边,将较小的数放到右边。如下:
if(sr[i]<sr[i+1]){
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
当i = 0时,便会将数组中索引为0的数和索引为1的数按从大到小排列。因此,当i依次递增时,如下:
for(int i=0; i<sr.length-1;i++){
if(sr[i]<sr[i+1]){
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
}
经过多次的交换之后,便将数组中最小值移到了数组末尾:
[43, 23, 65, 41, 54, 32, 12, 56, 22, 3]
进过一轮交换,我们将数组中最小的值移到了数组末尾,试想:如果将上面的交换重复sr.length-1次,那么我们就可以将数组中的值从大到小进行排序:
for(int j=0; j<sr.length-1; j++){
boolean sequence = true;
for(int i=0; i<sr.length-1;i++){
if(sr[i]<sr[i+1]){
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
}
}
System.out.println(Arrays.toString(sr));
结果:[65, 56, 54, 43, 41, 32, 23, 22, 12, 3]
虽然得到了结果,但分析上面的排序:当第一轮排列结束之后,已经将数组中最小的数值3放置到了sr[9]。
但第二轮排序时,我们仍然将sr[8]与sr[9]进行了比较。而经过第一轮排序之后,sr[9]显然已经是最小的,所以sr[8]与sr[9]的比较是毫无必要的。
同理我们可以分析得到后面几轮排序中有多次比较都是毫无必要的。经优化后的代码如下:
for(int j=0; j<sr.length-1; j++){
for(int i=0; i<sr.length-1-j;i++){
if(sr[i]<sr[i+1]){
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
}
}
System.out.println(Arrays.toString(sr));
结果:[65, 56, 54, 43, 41, 32, 23, 22, 12, 3]
最后,还可以进一步分析:如果其中经过某一次的排序之后,数组已经得到了我们想要的排序结果,那么后面的比较排序过程就可以省略了。
如何知道数组的排序结果已经是我们想要的?从下面的代码块可以得知:
for(int i=0; i<sr.length-1;i++){
if(sr[i]<sr[i+1]){
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
}
如果在某一轮比较中,如果数组的排序结果已经是我们想要的,那么代码将不会走到if语句中。
因此我们可以在if语句中添加一个判断条件,如果已经得到我们想要的结果,就可以在上述代码块结束之后,退出排序。最后代码如下:
for(int j=0; j<sr.length-1; j++){
boolean sequence = true;
for(int i=0; i<sr.length-1-j;i++){
if(sr[i]<sr[i+1]){
sequence = false;
int temp = sr[i];
sr[i] = sr[i+1];
sr[i+1] = temp;
}
System.out.println(Arrays.toString(sr));
}
if(sequence == true){
break;
}
}
System.out.println(Arrays.toString(sr));
结果和前面得到的结果一致。
水平所限,有所疏漏,多多包涵。。