`
阿尔萨斯
  • 浏览: 4167426 次
社区版块
存档分类
最新评论

经典算法详解 之 冒泡排序

 
阅读更多

排序算法对程序员来说是比较基础的东西,但是因为它们比较繁琐,所以有时候就容易弄混,特别是一些算法本身就很相似的话,就更难弄清楚它们之间的区别和联系!

排序可以分为内排序和外排序,一般我们所说的排序仅指的是内排序。这次我们来分别熟悉一下内部排序中的各种排!关于内排序和外排序,本为不做重点介绍!

在说排序之前,我们先熟悉一下排序中元素互换常用的三句代码:

temp=a;

a=b;

b=temp;

这三行代码的含义是利用temp这个临时仓库交换ab。这三句代码是比较经典的数据交换代码,可以确定的是任何语言的数据交换都可以类似的写成这个形式。当然你用的语言或者数据类型不同的话,也是需要稍微变化一下的,但是整体的思路是不会变动的。如果说不用temp这个临时仓库,写成:

a=a+b;

b=a-b;

a=a-b;

这三行代码来完成数据交换的话,那对读者来说可就不那么容易理解了,当然对一些代码特别敏感的变态除外。需要说的是:有时候数据类型之间如果不能进行加或减的运算,那么这上述三行代码可是会出报错的。

好了就下来就说一下最常用的排序——冒泡排序

为了让读者理解所谓的冒泡排序,我们概括一下冒泡排序的规则

冒泡排序的法则是:将一串待排序的数据从一个方向依次与第一个或最后一个进行比较,将正在进行比较的两数中的较大或较小的值,换到两个数相对较前或较后的位置上来,然后将本次得到的较大或较小的值与下一个数据元素进行比较,最终将待排序序列中的最值(最大或最小值)排到最前或最后,并且该最值不再参与下一次的比较。到此为止第一趟排序结束,接着进行下一趟的排序,直到第一个或最后一个数据为止。

接下来,我们来具几个简单的例子。

例:

	public class BubbleSort{
		public static void main(String[] args){
			int[] list={0,1,2,3,4,5,6,7,8,9};
			System.out.println("Before quick sort:");
			for(int i=0;i<list.length;i++){
				System.out.print(list[i]+" ");
			}
			
			bubbleSort(list);
			
			System.out.println("\n After quick sort:");
			for(int i=0;i<list.length;i++){
				System.out.print(list[i]+" ");
			}
		}
		
		//从右向左,右冒泡
		private static void bubbleSort(int[] list){
			for(int i=list.length-1;i>0;i--){
				for(int j=i-1;j>=0;j--){
					if(list[i]>list[j]){
						int temp=list[i];
						list[i]=list[j];
						list[j]=temp;
					}
				}
			}
		}
	}

以上是我们经常写的从右向左,右冒泡的冒泡排序算法它的规则是将一串待排序的数据从右方依次与最后一个进行比较,将正在进行比较两数中的较小的值,换到两个数相对较前的位置上来,然后将本次得到的较小的值与下一个数据元素进行比较,最终将待排序序列中的最小值排到最后,并且该最值不再参与下一次的比较。到此为止第一趟排序结束,接着进行下一趟的排序,直到第一个数据为止。

上述排序的过程得到的每一趟排序的结果如下:

原始数据:0 1 23 4 5 6 7 8 9

1趟排序:1 2 3 4 5 6 7 8 9 0比较时间:9单位

2趟排序:2 3 4 5 6 7 8 9 1 0比较时间:8单位

3趟排序:3 4 5 6 7 8 9 2 1 0比较时间:7单位

4趟排序:4 5 6 7 8 9 3 2 1 0比较时间:6单位

5趟排序:5 6 7 8 9 4 3 2 1 0比较时间:5单位

6趟排序:6 7 8 9 5 4 3 2 1 0比较时间:4单位

7趟排序:7 8 9 6 5 4 3 2 1 0比较时间:3单位

8趟排序:8 9 7 6 5 4 3 2 1 0比较时间:2单位

9趟排序:98 7 6 5 4 3 2 1 0比较时间:1单位

最终结果:9 8 7 6 5 4 3 2 1 0

将我们上述的排序算法适当调整就得到了从左向右,右冒泡的冒泡排序算法如下所示。它的规则是将一串待排序的数据从左方依次与最后一个进行比较,将正在进行比较两数中的较小的值,换到两个数相对较前的位置上来,然后将本次得到的较小的值与下一个数据元素进行比较,最终将待排序序列中的最小值排到最后,并且该最值不再参与下一次的比较。到此为止第一趟排序结束,接着进行下一趟的排序,直到最后一个数据为止。

具体的算法如下:

	//从左向右,右冒泡
	private static void bubbleSort(int[] list){
		for(int i=0;i<list.length-1;i++){
			for(int j=0;j<list.length-1-i;j++){
				if(list[j]<list[j+1]){
					int temp=list[j];
					list[j]=list[j+1];
					list[j+1]=temp;
				}
			}
		}

	}

上述排序的过程得到的每一趟排序的结果如下:

原始数据:0 1 23 4 5 6 7 8 9

1趟排序:1 2 3 4 5 6 7 8 90比较时间:9单位

2趟排序:2 3 4 5 6 7 8 91 0比较时间:8单位

3趟排序:3 4 5 6 7 8 92 1 0比较时间:7单位

4趟排序:4 5 6 7 8 9 3 2 1 0 比较时间:6单位

5趟排序:5 6 7 8 94 3 2 1 0比较时间:5单位

6趟排序:6 7 8 95 4 3 2 1 0比较时间:4单位

7趟排序:7 8 96 5 4 3 2 1 0比较时间:3单位

8趟排序:8 97 6 5 4 3 2 1 0比较时间:2单位

9趟排序:98 7 6 5 4 3 2 1 0比较时间:1单位

最终结果:9 8 7 6 5 4 3 2 1 0

上述两种右冒泡算法对比之后我们可以得到下面所示的这样一个三角形,它表示的含义就是参与排序的数据数量越来越小,最值就像气泡一样浮动到最右方。


当然我们也可以该动成:从左向右,左冒泡;从右向左,左冒泡具体算法如下:

	//从左向右,左冒泡
	private static void bubbleSort(int[] list){
		for(int i=0;i<list.length-1;i++){
			for(int j=i+1;j<list.length;j++){
				if(list[i]<list[j]){
					int temp=list[i];
					list[i]=list[j];
					list[j]=temp;
				}
			}
		}
	}
	
	//从右向左,左冒泡
	 private static void bubbleSort(int[] list){
		for(int i=0;i<list.length-1;i++){
			for(int j=list.length-1;j>i;j--){
				if(list[j]>list[j-1]){
					int temp=list[j];
					list[j]=list[j-1];
					list[j-1]=temp;
				}
			}
		}
	}

上述两种左冒泡得到的结果如下:

原始数据:0 1 23 4 5 6 7 8 9

1趟排序:9 0 1 2 3 4 5 6 7 8比较时间:9单位

2趟排序:9 8 0 1 2 3 4 5 6 7比较时间:8单位

3趟排序:9 8 7 0 1 2 3 4 5 6比较时间:7单位

4趟排序:9 8 7 6 0 1 2 3 4 5比较时间:6单位

5趟排序:9 8 7 6 5 0 1 2 3 4比较时间:5单位

6趟排序:9 8 7 6 5 4 0 1 2 3比较时间:4单位

7趟排序:9 8 7 6 5 4 3 0 1 2比较时间:3单位

8趟排序:9 8 7 6 5 4 3 2 0 1比较时间:2单位

9趟排序:9 8 7 6 5 4 3 2 1 0比较时间:1单位

最终结果:9 8 7 6 5 4 3 2 1 0

上述两种左冒泡算法对比之后我们也可以得到下面所示的这样一个三角形,它表示的含义就是参与排序的数据数量越来越小,最值就像气泡一样浮动到最左方。



接下再来我们再来介绍一个冒泡排序的最优算法。具体算法如下:

	//冒泡排序最优算法
	private static void bubbleSort(int[] list){
		boolean flag=false;//用于标识是否需要再次比较
		for(int i=0;i<list.length-1;i++){
			for(int j=0;j<list.length-1;j++){
				if(list[j]<list[j+1]){
					int temp=list[j];
					list[j]=list[j+1];
					list[j+1]=temp;
					flag=true;
				}
			}
			if(!flag)break;
		}
	}

上述算法的规则是从左向右,相邻的数进行比较交换,将最值移动到最右。当然如果读者又兴趣也可以自己写一个从右向左,相邻的数进行比较 交换,将最值移动到最左的冒泡排序算法上述算法得到结果如下:

原始数据:0 1 23 4 5 6 7 8 9

第一趟排序结果:0 1 2 3 4 5 6 7 8 9比较时间:9单位

最终结果:0 1 23 4 5 6 7 8 9

对比一下最优算法之前的四种排序,我们可以清楚的明白最优算法的好处,就是添加一个标识,用于记录是否需要进行第二趟的比较。这种算法从时间上来说,可以节省不必要的比较时间,当然最好时间是有条件的,即所做的排序序列已经是最终结果。

我们做个总结就可以得出这样一个结论:对于n个数比较从时间复杂度上来最好情况为O(n),而之前讲的四种时间复杂度我们可以很容易根据(9+8+7+6+5+4+3+2+1)这种规律,得出每趟所需时间n-in表示数据元素的个数,i表示第几趟),所需时间总和为n*n-1/2,最坏情况下时间复杂度O(n2)

到这里,我们的冒泡排序的规律基本已经解释清楚了,接下来就需要读者做更多的思考和实践了!




分享到:
评论

相关推荐

    java基础 经典算法之冒泡排序详解

    1.冒泡排序的原理:每次都从第一个元素开始(索引0),向后两两比较,只要后面的比前面的大,就交换(从大到小) 2.通过画图分析,5个数字排4趟,n数字排n-1趟,而外层的for循环代表的是循环的趟数,所以外层循环的结束条件是...

    JAVA冒泡排序算法详解

    从老师那弄的JAVA冒泡排序的一个讲解,不明白的可以好好看看哈

    详解Java常用排序算法-冒泡排序

    详解Java常用排序算法-冒泡排序

    java基础冒泡排序.ppt

    冒泡排序详解,简单而详细的讲清楚了,什么是冒泡排序。 冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。 它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首...

    C语言冒泡排序算法详解:从原理到代码的完整教程

    C语言冒泡排序的习题集,针对C语言冒泡排序算法的重要知识点和难点,提供了大量的练习题和考试题,以及详细的答案和解析,涵盖了冒泡排序算法的原理、步骤、实现方法、优化技巧、相关概念和知识等内容,以及冒泡排序...

    Python排序算法详解

    Python排序算法详解 Python排序算法——冒泡排序 Python排序算法——插入排序 Python排序算法——选择排序 Python排序算法——快速排序 Python排序算法——归并排序

    Scratch冒泡排序 Scratch排序算法讲解 Scratch高阶编程

    此案例难度系数4,属于Scratch高级编程,虽然是高阶编程范畴,但是冒泡排序相对而言也还是比较好理解的;综合考查说话、随机数、无限循环(条件循环)、条件判断、变量定义和使用、列表定义和使用、自定义积木的定义...

    冒泡排序的算法详解PPT教案学习.pptx

    冒泡排序的算法详解PPT教案学习.pptx

    C语言 冒泡排序算法详解及实例

    C语言 冒泡排序算法 冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说...

    Javascript冒泡排序算法详解

    主要介绍了Javascript冒泡排序算法的相关资料,需要的朋友可以参考下

    详解python算法之冒泡排序

    主要介绍了详解python算法之冒泡排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    C#实现所有经典排序算法

    文介绍了C#的四种排序算法:冒泡排序、选择排序、插入排序和希尔排序 冒泡排序 using System; namespace BubbleSorter { public class BubbleSorter { public void Sort(int [] list) { int i,j,temp; bool done=...

    c++冒泡排序详解

    冒泡排序,作为最基本的排序算法,由于原理像冒泡一样,所以取名为冒泡排序; 我们知道,水泡在上升时,总是密度最小的最先上去,假如一个水层只能容纳一个水泡,那么水泡由上到下的排序就是密度逐渐增大的排序。...

    冒泡排序和选择排序的详解(包含图解和java代码)

    a) 冒泡排序:相邻的两个元素进行比较,如果前者大于后者,则交换位置,保证每一次的比较都将最大值向后移动。 b) 选择排序:每一次从待排序的元素中选出最小值,存放在数组的起始位置,直到全部待排序的元素排完...

    PHP排序算法之冒泡排序(Bubble Sort)实现方法详解

    本文实例讲述了PHP排序算法之冒泡排序(Bubble Sort)实现方法。分享给大家供大家参考,具体如下: 基本思想: 冒泡排序是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的...

    7大排序算法详解文档及java代码实现(可直接运行)

    7大排序算法详解文档,包括冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序。附带java代码实现,可以直接运行。

    java 算法之冒泡排序实例详解

    主要介绍了java 算法之冒泡排序实例详解的相关资料,冒泡排序,就是模仿泡泡从水中浮起跑到水面的过程需要的朋友可以参考下

    JS排序之冒泡排序详解

    本文为大家分享了JS冒泡排序的具体代码,供大家参考,具体内容如下 说明 时间复杂度指的是一个算法执行所耗费的时间 空间复杂度指运行完一个程序所需内存的大小 稳定指,如果a=b,a在b的前面,排序后a仍然在b的前面 ...

Global site tag (gtag.js) - Google Analytics