冒泡排序
一个数组里面的元素,拿最左边的和它右边的元素比较,如果左边的大,则交换位置,如果右边的大,则不交换;再拿第二个元素和第三个元素比较,如果第二个大,则交换位置,如果第三个大,则不交换;直到最后一个.
举例来说,数组 int[] arr = {6,1,2,8,0,7}; (0,1,2,3,4,5)
第一次循环:
参与比较的数据:6 1 2 8 0 7(6和1比较,6和1交换位置)
第一次比较的结果:1 6 2 8 0 7(6和2比较,6>2,6和2交换位置)
第二次比较的结果:1 2 6 8 0 7(6和8比较,6<8,不交换位置)
第三次比较的结果:1 2 6 8 0 7(8和0比较,8>0,8和0交换位置)
第四次比较的结果:1 2 6 0 8 7(8和7比较,8>7,8和7交换位置)
第五次比较的结果:1 2 6 0 7 8
第二次循环:
参与比较的数据:1 2 6 0 7(1和2比较,1<2,不交换位置)
第一次比较的结果:1 2 6 0 7(2和6比较,2<6,不交换位置)
第二次比较的结果:1 2 0 6 7(6和0比较,6>0,6和0交换位置)
第三次比较的结果:1 2 0 6 7(6和7比较,6<7,不交换位置)
第四次比较的结果:1 2 0 6 7
第三次循环:
参与比较的数据:1 2 0 6(1和2比较,1<2,不交换位置)
第一次比较的结果:1 2 0 6(2和0比较,2>0,2和0交换位置)
第二次比较的结果:1 0 2 6(2和6比较,2<6,不交换位置)
第三次比较的结果:1 0 2 6
第四次循环:
参与比较的数据:1 0 2(1和0比较,1>0,1和0交换位置)
第一次比较的结果:0 1 2(1和2比较,1<2,不交换位置)
第二次比较的结果:0 1 2
第五次循环:
参与比较的数据:0 1(0和1比较,0<1,不交换)
第一次比较的结果:0 1
if(arr[i] > arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
6个数据,外循环是5次,内循环分别是5,4,3,2,1次.
arr长度为6,i从0开始,0,1,2,3,4,共5次外循环.
倒过来想,for循环中,外循环按i--;的方式来,从5到1,也是5次,而内循环j当i=5时从0到4(5次),当i=4时从0到3(4次),当i=1时j=0(1次),也就是:
for(int i = 5; i > 0; i--){//这个5其实是arr.length - 1
for(int j = 0; j < i; j++){
if(arr[j] > arr[j+1]){
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
这种排序方法,比较次数是15次,交换位置次数是7次.
选择排序
每一次从数组中这堆参与比较的数据中找出最小值,拿着这个最小值与最前面的数据交换位置.
举例来说,数组 int[] arr = {6,1,2,8,0,7}; (0,1,2,3,4,5)
参与比较的数据:6 1 2 8 0 7(最小值是0,6和0交换位置)
第一次循环:比较之后的结果:(0) 1 2 8 6 7(0不管了,因为它最小,后面的最小值是1,不交换位置)
第二次循环:比较之后的结果:(0 1) 2 8 6 7(0,1不管了,因为它最小,后面的最小值是2,不交换位置)
第三次循环:比较之后的结果:(0 1 2) 8 6 7(0,1,2不管了,因为它最小,后面的最小值是6,8和6交换位置)
第四次循环:比较之后的结果:(0 1 2 6) 8 7(0,1,2,6不管了,因为它最小,后面的最小值是7,8和7交换位置)
第五次循环:比较之后的结果:(0 1 2 6 7) 8
6个数据,外循环5次,内循环分别是5,4,3,2,1次.
假设arr[0]是最小的,当i=0时,arr[0]和arr[1]比较,6>1,arr[0]并不是最小的,把最小值赋给arr[1],arr[1]再和arr[2]比较,1<2,arr[1]还是最小的,arr[1]和arr[3]比较,1<8,arr[1]还是最小的,arr[1]和arr[4]比较,1>0,arr[1]并不是最小的,把最小值赋给arr[4],arr[4]和arr[5]比较,0<7,所以最小值是arr[4].然后把arr[4]和arr[0]交换位置.第一次循环结束.此时arr[0]的位置是当前的最小值.即(0) 1 2 8 6 7.(0)不再参与比较.
当i=1时,此时的假设最小值是arr[1],arr[1]和arr[2]比较,1<2,arr[1]还是最小的,arr[1]和arr[3]比较,1<8,arr[1]还是最小的,arr[1]和arr[4]比较,1<6,arr[1]还是最小的,arr[1]和arr[5]比较,1<7,arr[1]还是最小的,最小值不变,不需要交换位置.第二次循环结束.此时arr[1]的位置是当前的最小值.即(0 1) 2 8 6 7.(0 1)不再参与比较.
当i=2时,此时的假设最小值是arr[2],arr[2]和arr[3]比较,2<8,arr[2]还是最小的,arr[2]和arr[4]比较,2<6,arr[2]还是最小的,arr[2]和arr[5]比较,2<7,arr[2]还是最小的,最小值不变,不需要交换位置.第三次循环结束.此时arr[2]的位置是当前的最小值.即(0 1 2) 8 6 7.(0 1 2)不再参与比较.
当i=3时,此时的假设最小值是arr[3],arr[3]和arr[4]比较,8>6,arr[3]不是最小的,把最小值赋给arr[4],arr[4]和arr[5]比较,6<7,arr[4]还是最小的,arr[4]和arr[3]交换位置.第四次循环结束.此时arr[3]的位置是当前的最小值.即(0 1 2 6) 8 7.(0 1 2)不再参与比较.
当i=4时,此时的假设最小值是arr[4],arr[4]和arr[5]比较,8>7,arr[4]不是最小的,把最小值赋给arr[5],arr[4]和arr[5]交换位置.第五次循环结束.此时arr[4]的位置是当前的最小值.即(0 1 2 6 7) 8.退出循环.
以上可以看到,当外循环为i时,将i的值赋给最小值min的下标,然后让arr[min]和arr[i+1]比较,如果arr[i+1]<arr[min],则将i+1的值赋给最小值的下标,当一轮循环结束后,如果min没有变,说明最小值就是arr[i],如果变了,则要把arr[i+1]与arr[min]交换位置.
当i的值不变时(比如为0),则只能比较arr[0]和arr[1],无法从arr[0]循环到arr[5],而当i=1时,循环则从arr[1]到arr[5]..当i=4时,循环从arr[4]到arr[5].
内循环需要一个变量j=i+1;j<arr.length;j++
for(int i = 0; i < arr.length - 1; i++){
int min = i;
for(int j = i + 1; j < arr.length; j++){
if(arr[j] < arr[min]){
min = j;
}
}
if(min != i){
int temp;
temp = arr[min];
arr[min] = arr[i];
arr[i] = temp;
}
}
交换位置不太好理解,可以想象是两只手拿着东西,左手拿着6(arr[i]),假设的最小值,右手拿着取到的最小值0(arr[min]),现在int temp,就像一个桌子,先把取到的最小值(右手的东西arr[min])放到桌子上(temp),现在右手空了,再把左手拿的假设的最小值6(arr[i])放到右手(arr[min]),现在左手空了,再把桌子上(temp)的东西(也就是最小值arr[min])放到左手(arr[i]),这样就实现了交换位置.