冒泡排序

今天数据结构开课啦,第一节冒泡排序

 1、解说:冒泡,顾名思义是小的数字往上冒,此处我们可以理解有一个数组,最终要求的结果是数组的排序顺序是从小到大,可以形象的认为,每个数字是一个气泡,当后面的数字小的时候,就往上冒。我们从数组的最后的位置开始两两比较 (index) 和 (index-1) 两个位置的数据,如果 (index-1) 大于 (index)则二者交换位置,交换之后,index-1 再跟前面的比,直到排序结束;


举例,如果有一组数是【1,5,8,7,4】

第一趟

i   

                        j-1     j

1      5      8      7      4

                j-1    j

1      5      8      4      7

        j-1     j

1      5      4      8      7

 j-1    j                   

1      4      5      8      7

1      4      5      8      7


第二趟

        i

                        j-1     j

1      4      5      8      7

               j-1     j

1      4      5      7      8

………………

从上例可以看出正确排序已经出现,但是实际上代码还在运行,直至所有的循环走完


**********华丽的分割线************


2、代码:(冒泡排序可实现的代码有很多种,下面是其中一种)

public class BubbleSort {

	public static void main(String[] args) {
		int[] a = { 1, 5, 8, 7, 4 };
		int temp = 0;
		for (int i = 0; i < a.length; i++){
			for (int j = a.length - 1; j > 0; j--){
				if (a[j - 1] > a[j]){
					temp = a[j];
					a[j] = a[j - 1];
					a[j - 1] = temp;
				}
			}
		}
	}
}


3、是否是稳定算法:是

冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。

4、复杂度:

若文件的初始状态是正序的,一趟扫描即可完成排序。所需的关键字比较次数C和记录移动次数M均达到最小值:Cmin=n-1,Mmin=0。冒泡排序最好的时间复杂度为O(n)。

若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1≤i≤n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较和移动次数均达到最大值:Cmax=n(n-1)Π2=O(n²),Mmax=3n(n-1)Π2=O(n²)。冒泡排序最坏情况的时间复杂度是O(n²)

算法的平均时间复杂度为O(n²)。虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均时间性能比直接插入排序要差得多。

5、优化:

上面我们已经看到,当正确的排序已经出现的时候,循环依然在继续,直到完成,这也太浪费资源了,我们可以设置一个标识符。

public class BubbleSort {
	public static void main(String[] args) {
		boolean k = true;
		int[] a = { 1, 5, 8, 7, 4 };
//		int[] a = { 1, 2, 3, 4, 5 };
		int temp = 0;
		for (int i = 0; i < a.length && k; i++) {
			k = false;//只要flag在下一次外循环条件检测的时候值为false,就说明已经排好序,不用继续循环 
			for (int j = a.length - 1; j > 0; j--) {
				if (a[j - 1] > a[j]) {
					temp = a[j];
					a[j] = a[j - 1];
					a[j - 1] = temp;
					k = true;// 如果有交换,就将标记变量赋true
				}
				System.out.println(i);// sysout,然后快捷键Alt+/
			}

		}
	}
}





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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值