Java算法实现之冒泡排序及优化

冒泡排序,是一种很简单的排序算法。原理就不过多介绍了,直接入手demo。

需求:输入一组数据,用冒泡排序进行排序。

先用最直接的方法进行排序,代码如下:

//对一组数进行冒泡排序
public class Bubble01 {
	public static void main(String[] args) {
		int flag = 0;//用于记录次数
		int num[] = {1,23,54,5,21,51,41,23,15,47};//模拟输入数组
		for (int i = 0; i < num.length - 1; i++) {//外层循环,用于控制循环次数。一共需要循环n(数组大小)-1次
			for (int j = 1; j < num.length - i; j++) {//内层循环,用于数据比较第一次比0~n的数第二次0~n-1……
				if(num[j] < num[j-1]){
					int temp = num[j];
					num[j] = num[j-1];
					num[j-1] = temp;
				}
				flag++;//记录次数
			}
		}
		for (int i : num) {
			System.out.print(i + " ");//输出目标数组
		}
		System.out.println("\n循环次数:" + flag);//输出循环次数
	}
}
输出结果:

1 5 15 21 23 23 41 47 51 54 
循环次数:45
但是,这种效率是很低的,我们仔细想想,如果数组是 1 2 4 3 5 6 7 8 9,按照上面的方法,第一次循环,在3和4交换之后,数组变成 1 2 3 4 5 6 7 8 9,按照第一种方法来说,接下来会进行 1 2 3 4 5 6 7 8的第二次循环,可是我们可以明显知道,接下来是不应该继续下去了,已经成为了有序数列。那么我们应该怎么样减少“浪费”的循环呢?于是我们可以设置一个循环标记isExit,在下一次循环之前,我们把这个标记设为false,如果在下一次循环里面有数字的交换,那么说明下一次循环之后的结果不一定是排序好的结果,直到接下来循环没有出现过数字的交换的时候,那么这次一定为排序后的序列。

理解起来很简单,优化方式一,代码如下:

//冒泡排序优化版本1
public class Bubble02 {
	public static void main(String[] args) {
		int flag = 0;//用于记录次数
		int num[] = {1,23,54,5,21,51,41,23,15,47};//模拟输入数组
		boolean isExit = true;//是否继续循环标志
		int j = num.length;//下次循环截止位置
		while(isExit){
			isExit = false;//如果for循环完成之后,该标记未改变说明数组已经为有序,则退出循环。
			for (int i = 1; i < j; i++) {
				if(num[i] < num[i-1]){
					int temp = num[i];
					num[i] = num[i-1];
					num[i-1] = temp;
					isExit = true;//如果for循环完成之后,该标记已经改变说明数组可能还未有序,则继续循环。
				}
				flag++;//记录次数
			}
			j--;//下一次就减少一位
		}
		for (int i : num) {
			System.out.print(i + " ");//输出目标数组
		}
		System.out.println("\n循环次数:" + flag);//输出循环次数
		
	}
}
输出结果:

1 5 15 21 23 23 41 47 51 54 
循环次数:42
哈哈,循环次数确实减少了呢!但是我们再仔细想一想,数组1 2 4 3 5 6 7 8 9,第一次循环交换结束后为 1 2 3 4 5 6 7 8 9,则接下来进行第二次循环,循环范围为 1 2 3 4 5 6 7 8,按照第一种优化方式,我们会把数组 1 2 3 4 5 6 7 8全部比一遍,发现已经没有数字交换了,那么应该为排序数组了,符合了要求。但是我们第二次有必要去把 1 2 3 4 5 6 7 8全部比一遍吗?我们交换了 4 3的位置,后面的5 6 7 8 9并没有交换,则可以默认交换位置之后的数列为有序数列,所以第二次其实只需要看1 2 3 4 是不是有序数列就可以了,这样也减少了大量的次数呢!

优化方式二,代码如下。

//冒泡排序优化版本2
public class Bubble03 {
	public static void main(String[] args) {
		int flag = 0;//用于记录次数
		int num[] = {1,23,54,5,21,51,41,23,15,47};//模拟输入数组
		boolean isExit = true;//是否继续循环标志
		int j = num.length;//下次循环截止位置
		int k = 0;//记录最后一次交换的位置,k之后的说明已经是排好顺序的了
		while(isExit){
			isExit = false;
			for (int i = 1; i < j; i++) {
				if(num[i] < num[i-1]){
					int temp = num[i];
					num[i] = num[i-1];
					num[i-1] = temp;
					k = i;//记录交换位置
					isExit = true;
				}
				flag++;//记录次数
			}
			j = k;//下次循环的截止位置应该是为最后一次交换的位置
		}
		for (int i : num) {
			System.out.print(i + " ");//输出目标数组
		}
		System.out.println("\n循环次数:" + flag);//输出循环次数
	}
}
输出结果:

1 5 15 21 23 23 41 47 51 54 
循环次数:38

优化方式是自己摸索出来的,也不知道是否正确,如有不正确的地方,欢迎点评。



猜你喜欢

转载自blog.csdn.net/a445849497/article/details/55099723