排序算法之冒泡排序

概念(实现思想)

百度解释:它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

**个人理解**: 一次只比较两个数字 (第一个数字依次与后面的数字进行比较,如果大于(小于),则与后面的数字交换位置,保证每一次循环结束,最后一位的数字是最大值(最小值)。第二次将进行i-1次循环)。

时间复杂度为O(N^2),是稳定算法。

举例

原始序列:{10,1,35,61,89,36,55}

第一趟排序:

第一次排序:10和1比较,10大于1,交换位置      [1,10,35,61,89,36,55]

第二趟排序:10和35比较,10小于35,不交换位置  [1,10,35,61,89,36,55]

第三趟排序:35和61比较,35小于61,不交换位置  [1,10,35,61,89,36,55]

第四趟排序:61和89比较,61小于89,不交换位置  [1,10,35,61,89,36,55]

第五趟排序:89和36比较,89大于36,交换位置    [1,10,35,61,36,89,55]

第六趟排序:89和55比较,89大于55,交换位置   [1,10,35,61,36,55,89]

第一趟总共进行了六次比较,排序结果: [1,10,35,61,36,55,89]

第二趟排序:

第一次排序:1和10比较,1小于10,不交换位置   [1,10,35,61,36,55,89]

第二次排序:10和35比较,10小于35,不交换位置 [1,10,35,61,36,55,89]

第三次排序:35和61比较,35小于61,不交换位置 [1,10,35,61,36,55,89]

第四次排序:61和36比较,61大于36,交换位置   [1,10,35,36,61,55,89]

第五次排序:61和55比较,61大于55,交换位置   [1,10,35,36,55,61,89]

第二趟总共进行了5次比较,排序结果: [1,10,35,36,55,61,89]

第三趟排序:

1和10比较,1小于10,不交换位置   [1,10,35,36,55,61,89]

第二次排序:10和35比较,10小于35,不交换位置 [1,10,35,36,55,61,89]

第三次排序:35和36比较,35小于36,不交换位置 [1,10,35,36,55,61,89]

第四次排序:36和61比较,36小于61,不交换位置  [1,10,35,36,55,61,89]

第三趟总共进行了4次比较,排序结果: [1,10,35,36,55,61,89]

代码实现

一、普通代码实现

public static void bubble(int[] arr) {
	if(arr==null || arr.length<2) {
		return;
	}
	
	//外层循环控制排序的趟数
	for(int x=arr.length-1;x>0;x--) {
		//内层循环控制当前趟数需要比较的次数
		for(int i = 0;i<x;i++) {
			//当前位置的数与后一位进行比较,如果大于后一位,进行交换
			if(arr[i]>arr[i+1]) {
				swap(arr,i,i+1);
			}
		}
		
	}
	
}

private static void swap(int[] arr, int i, int j) {
	int temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;	
}

二、优化后的冒泡排序

实现思想: 如果在某躺排序中没有发生交换位置,那么我们可以认为该数组已经排好序了。 这也不难理解,因为 我们每趟排序的目的就是将当前趟最大的数置换到对应的位置上,没有发生置换说明就已经排好序了。

	public static void bubble(int[] arrays) {
	// 装载临时变量
	int temp;
	int num = 0;
	// 记录是否发生了置换, 0 表示没有发生置换、 1 表示发生了置换
	int isChange;

	// 外层循环是排序的趟数
	for (int i = 0; i < arrays.length - 1; i++) {
		// 每比较一趟就重新初始化为0
		isChange = 0;
		// 内层循环是当前趟数需要比较的次数
		for (int j = 0; j < arrays.length - i - 1; j++) {

			// 前一位与后一位与前一位比较,如果前一位比后一位要大,那么交换
			if (arrays[j] > arrays[j + 1]) {
				temp = arrays[j];
				arrays[j] = arrays[j + 1];
				arrays[j + 1] = temp;
				
				//如果进到这里面了,说明发生置换了
			      isChange = 1;
			}
		}
		// 如果比较完一趟没有发生置换,那么说明已经排好序了,不需要再执行下去了
		if (isChange == 0) {
			break;
		}
		num++;
	}
	System.out.println(num);

与选择排序的对比

1)冒泡排序是比较相邻位置的两个数,而选择排序是按顺序比较,找最大值或者最小值;

2)冒泡排序每一轮比较后,位置不对都需要换位置,选择排序每一轮比较都只需要换一次位置;

3)冒泡排序是通过数去找位置,选择排序是给定位置去找数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值