java冒泡排序的实现以及优化

冒泡排序原理:

1、比较相邻的两个元素,如果前者大于后者则交换位置;

2、这样对数组第0个数据到N-1个数据进行遍历比较一次后,最大的数据会移动到最后一位。

3、N=N-1,如果N=0则排序完成;

代码实现

package zks;

public class BubbleSort {
	public static void Bubble(int a[],int n){
		int i,j;
		for(i = 0;i < n;i++){//N次排序
			for(j = 1;j < n - i;j++){//每循环一次取出最大值放在数组的n-i位;
				if(a[j - 1] > a[j]){//相邻元素比较
					int temp;
					temp = a[j];
					a[j] = a[ j- 1];
					a[j - 1] = temp;//替换元素
				}
			}
		}
	}
} 
package zks;

public class Main {
	public static void main(String args[]){
		int[] arr = {1,1,2,0,9,33,21,7,13,3,35,65,22};
		BubbleSort.Bubble(arr, arr.length);
		for(int i = 0;i<arr.length;i++){
			System.out.print(arr[i]+",");
		}
	}
}

输出结果如下:


上面这个是最基本的冒泡排序方法,如果说数组数量比较大并且有一部分是本来就有序的,那么将会在此部分浪费时间。所有考虑到这种情况,可以事先设置一个标识flag,如果此次循化下来发生了交换,则为true,否则说明排序已完成,为false。

代码如下:

package zks;

public class BubbleSort {
		public static void Bubble2(int a[],int n){
			 int j, k = n;
			    boolean flag = true;//发生了交换就为true, 没发生就为false
			    while (flag){
			        flag=false;//每次开始排序前,都设置flag为未排序过
			        for(j=1; j<k; j++){
			            if(a[j-1] > a[j]){
			                int temp;
			                temp = a[j-1];
			                a[j-1] = a[j];
			                a[j]=temp;
			                //表示交换过数据;
			                flag = true;
			            }
			        }
			        k--;//减小一次排序的尾边界
		}
	}
}

结果如下:


在此优化的基础上考虑到,如果有一个包含500个数值的数组,前100个是无序的,后400个全部是有序排列好的并且后面的400个数值的最低值都大于前100个的最高值。如果用第二种方法的话,虽然也是只会比较100次,但是每一次都会与后面400位相比较,而用下面的方法只需要与后面400位比较一次,便会记录下这个标识然后设置尾边界,以后的99次便不会与后面400相比较

再次优化后代码如下:

package zks;

public class BubbleSort {
	public static void Bubble3(int [] a, int n){
	    int j , k;
	    int flag = n ;//flag来记录最后交换的位置,也就是排序的尾边界

	    while (flag > 0){//flag>0的话说明排序未结束
	        k = flag; //k 来记录遍历的尾边界
	        flag = 0;
	        for(j=1; j<k; j++){
	            if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换
	                //交换a[j-1]和a[j]
	                int temp;
	                temp = a[j-1];
	                a[j-1] = a[j];
	                a[j]=temp;

	                //表示交换过数据;
	                flag = j;//记录最新的尾边界.
	            }
	        }
	    }
	}
}

结果如下:


此方法相比之前的两种相对更友好一些;


猜你喜欢

转载自blog.csdn.net/zks_4826/article/details/80597450