冒泡排序

一)算法介绍

冒泡排序是一种入门级的稳定排序算法。

该名称的由来是因为越大的元素会经过交换,慢慢“浮”到顶端。

稳定排序:如果a原本在b前面,而a=b,排序之后a仍然在b的前面;

 

二)算法原理

基本原理:比较相邻的两个元素。如果第一个比第二个大,就交换他们两个。对每一对相邻的元素作同样的工作,从开始第一对到结尾的最后一对。最后的元素应该会是最大的数。

算法步骤图解(从head到last,依次从小到大排列)

源数据

第一遍排序:从head开始比较,5<6,5和6位置不变,再比较6>3,交换6和3的位置,再比较6>1,交换6和1的位置,再比较6<8,6和8位置不变,再比较8>7,交换8和7的位置,再比较8>2,交换8和2的位置,再比较8>4,交换8和4的位置,8是最大的数,排列再最后一位。

第二遍排序:从head开始比较,5>3,交换5和3的位置,再比较5>1,交换5和1的位置,再比较5<6,5和6位置不变,再比较6<7,6和7位置不变,再比较7>2,交换7和2的位置,再比较7>4,交换7和4的位置,不需要和8比较了。

第三遍排序:从head开始比较,3>1,交换3和1的位置,再比较3<5,3和5位置不变,再比较5<6,5和6位置不变,再比较6>2,交换6和2的位置,再比较6>4,交换6和4的位置,不需要和78比较了。

第四遍排序:从head开始比较,1<3,1和3位置不变,再比较3<5,3和5位置不变,再比较5>2,交换5和2的位置,再比较5>4,交换5和4的位置,不需要和678比较了。

第五遍排序:从head开始比较,1<3,1和3位置不变,再比较3>2,交换3和2的位置,再比较3<4,3和4位置不变,不需要和5678比较了。排序已完成。

算法复杂度:

最差情况:T(n) = O(n^2)

最好情况:T(n) = O(n),在所有元素已经排好序的情况(只需要比较一次)

// n=100;
// O(n)含义
for(i=0;i<100;i++){
}

// O(n^2)含义
for(i=0;i<100;i++) {
    for(i=0;i<100;i++){
    }
}

 

)算法源码

第一种方式:冒泡排序每比较完一遍,就可以确定最大数的位置,最大数会排列到最后面一位,下次不需要再重复比较,所以每循环一遍,次数就需要减1。

public static int[] bubbleSort(int[] nums) {
	if (nums == null) {
		return null;
	}
		
	for (int i = 0; i < nums.length; i++) {
		for (int j = 0; j < nums.length - 1 - i; j++) { 
			if (nums[j] > nums[j+1]) {
				int temp = nums[j];
				nums[j] = nums[j+1];
				nums[j+1] = temp;
			}
		}
	}
		
	return nums;
}

第二种方式:在第一种方式基础上,由于比较的时候,有一些元素已经是有序的(有序元素可以不需要再比较),可以记录上次比较的位置,在进行下一轮比较的时候,到达该位置时,就可以不需要比较了(因为已经有序了,重复比较没意义)。

public static int[] bubbleSortMax(int[] nums) {
	if (nums == null) {
		return null;
	}
		
	int border = nums.length - 1;
	int lastIndex = 0; // 记录内循环的下标
		
	for (int i = 0; i < nums.length; i++) {
		boolean isSorted = true; // 初始化
			
		for (int j = 0; j < border; j++) { // 如果发现后面是有序的,可以缩小每一轮比较的边界
			if (nums[j] > nums[j+1]) {
				int temp = nums[j]; // 声明一个临时变量存储
				nums[j] = nums[j+1];
				nums[j+1] = temp;
					
				isSorted = false; // 记录是否已经排序
				lastIndex = j; // 记录本次比较的边界
			}
		}
			
		// 如果已经排序完,就跳出循环
		if (isSorted) {
			break;
		}
		border = lastIndex; // 记录最后一个排序的边界, 因为边界后面都是已经排好序的
	}
		
	return nums;
}

 

识别二维码关注个人微信公众号

本章完结,待续,欢迎转载!
 
本文说明:该文章属于原创,如需转载,请标明文章转载来源!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值