很没写排序算法了,忽然就想写一下,写了一个算法程序,本来要写的是冒泡的,之后分析了下,结果写成了直接选择排序;
格式可能像冒泡排序,但思路却是直接选择排序,:
分析了下思路,下面是选择排序:
public void sortBull() { int[] arr = { 1, 3, 1, 4, 5, 0, 2 }; for (int i = 0; i < arr.length-1; i++) { for (int j = i; j < arr.length – 1; j++) { if (arr[i] > arr[j + 1]) { int iTemp; iTemp = arr[i]; arr[i] = arr[j + 1]; arr[j + 1] = iTemp; } } } }
//a[0]与a[1]比较,如果a[0]大于a[1],则交换位置,小的数存在a[0]中,大的数存在a[1中];否则不交换;然后,j++;变成了a[0]与a[2]较,所以第一次执行内层for循环
实际上是a[0]与与它后面的a[1]、a[2]..a[6]都进行了比较,最小的数存在a[0]中了;第二次执行内层for循环时,从a[1]开始比较,a[0]不再参与比较了!……以此类推
总结了一下选择排序基本思路:
第一次内层循环,选择一个最小的数放在第一个位置(a[0]);第二次内层循环,选择次最小的数,放在第二个位置(a[1]);…….整个循环结束.
而冒泡排序的基本思路是:
第一次 内层循环首先第一个数a[0]与第二个数a[1]比较(从小到大),然后第二个数a[1]与第三个数a[2]比较;第三个数a[2]与第四个数a[3]……第一内层循环结束;第二次内层循环(这里有个问题,就是每一次内层循环结束后,在最右边会产生一个不需要比较的数,循环在这里要控制好)还是第一个数a[0]与第二个数a[1]比较;第二个数a[1]与第三个数a[2]比较;到a[4]与a[5]比较完后,就不用比较了,因为第一次比较时,最大的数已经在最右边了(相当于是最大的数往上冒)!第一次内循环,就少比较一次;这样直到结束;
下面才是正确的冒泡排序
for(int i=0;i<arr.length-1;i++){ //这里是大数往上冒 for(int j=0;j<arr.length-i-1;j++){ //就这里有点区别:不仔细看,长得还真一样啊!呵呵, if(arr[j]>arr[j+1]){ //这里的(int j=0)j必须从0开始,(j<arr.length-i-1);这个条件很重要 int iTemp=0; iTemp = arr[j]; //这里的交换条件也有区别,数组里的下标是同一个变量 arr[j] = arr[j+1]; arr[j+1] = iTemp; } } }
改进冒泡排序算法:通过添加标志位。如果一趟排序没有数据进行交换(也就是没有执行if块代码),说明后面的顺序已经是正确的,没有再必要冒泡了,这样可以提高算法性能
public void sortBull() { int[] arr = { 1, 3, 1, 4, 5, 0, 2 }; boolean flag; for(int i=0;i<arr.length-1;i++){ flag = true; //引入一个特征标志, for(int j=0;j<arr.length-i-1;j++){ if(arr[j]>arr[j+1]){ //这里是大数往上冒 int iTemp = 0; iTemp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = iTemp; flag = false; //如果此趟排序没有数据进行交换,那么排序就结束,此句也不会执行 } } if(flag==true)break;//当没有数据进行交换时,提前终止循环,提高效率! } }