冒泡排序算法
Posted 勿忘初心-Lislie杰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了冒泡排序算法相关的知识,希望对你有一定的参考价值。
前面两篇介绍了两个非常简单和基础的排序算法——选择排序和插入排序,除了这两个,冒泡排序也是非常简单的一种排序算法。同样,本篇主要从“基本原理、排序流程、核心代码、算法性能、稳定性、参考代码”等几个方面介绍这一算法。
基本原理:依次比较两个相邻元素的大小,如果前一个元素大于(或小于)后一个元素,则两个元素交换位置。这样每一趟都能确定一个最大(或最小)的元素,每一趟都能把最大(或最小)的元素放到最后,直到所有元素都有序为止。
排序流程:以下以序列:5 3 0 4 1 9 7 2 6 8为例,加粗元素表示每一趟参与比较的元素,未加粗元素表示已经排好的元素(未参与比较),红色元素表示每一趟排好的最大元素。
趟数 | 排序前 | 排序后 | 说明 |
1 | 5 3 0 4 1 9 7 2 6 8 | 3 0 4 1 5 7 2 6 8 9 | 9元素最大,移动到最后面位置,此时9元素位置已定 |
2 | 3 0 4 1 5 7 2 6 8 9 | 0 3 1 4 5 2 6 7 8 9 | 8元素最大,移动到9元素前面位置,8元素位置已定 |
3 | 0 3 1 4 5 2 6 7 8 9 | 0 1 3 4 2 5 6 7 8 9 | 7元素最大,移动到8元素前面位置,7元素位置已定 |
4 | 0 1 3 4 2 5 6 7 8 9 | 0 1 3 2 4 5 6 7 8 9 | 6元素最大,移动到7元素前面位置,6元素位置已定 |
5 | 0 1 3 2 4 5 6 7 8 9 | 0 1 2 3 4 5 6 7 8 9 | 5元素最大,移动到6元素前面位置,5元素位置已定 |
6 | 0 1 2 3 4 5 6 7 8 9 | 0 1 2 3 4 5 6 7 8 9 | 4元素最大,移动到5元素前面位置,4元素位置已定 |
7 | 0 1 2 3 4 5 6 7 8 9 | 0 1 2 3 4 5 6 7 8 9 | 3元素最大,移动到4元素前面位置,3元素位置已定 |
8 | 0 1 2 3 4 5 6 7 8 9 | 0 1 2 3 4 5 6 7 8 9 | 2元素最大,移动到3元素前面位置,2元素位置已定 |
9 | 0 1 2 3 4 5 6 7 8 9 | 0 1 2 3 4 5 6 7 8 9 | 1元素最大,移动到2元素前面位置,1元素位置已定 |
最终排序结果为:0 1 2 3 4 5 6 7 8 9。最后一趟由于只比较了前两个元素,后面所有元素都已有序,所以此趟结束之后,序列已经有序了。需要注意的是,每一趟排序都能确定最大(或最小)的元素,但发生移动的元素可能不仅仅是最大(或最小)的元素,比如第一趟中5元素的位置发生改变。可以看出,如果序列长度为N,则总共进行了N-1趟排序,每一趟都能确定一个元素,所以下一趟参与比较的元素会比上一趟少一个。
核心代码:以Java为例。
public static void sort(int[] a){ int n = a.length; //序列长度 for (int i = 0; i < n-1; i++){ //排序趟数 for (int j = 0; j < n-i-1; j++){ if (a[j + 1] < a[j]){ int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } }
算法性能:对于所有元素都相等或者已经有序的序列,只会进行(N-1)+(N-2)+……+1=N(N-1)/2次比较,不会发生任何移动;对于逆序序列,同样会进行N(N-1)/2次比较,但每次比较都会交换元素,每次交换都会移动两个元素,所以会有N(N-1)次移动。总的来说,时间复杂度为O(N²),空间复杂度为O(1)。
稳定性:冒泡排序就是不断把大的元素移动到序列后面的过程,每次比较都是相邻的两个元素比较,交换也是相邻的两个元素交换。所以如果序列中有两个或多个元素相等,排序的时候不会发生交换;如果两个或多个相等的元素没有相邻,那么即使通过前面的两两交换把它们相邻起来,它们之间也不会发生交换,这样相等的元素相对位置并没有改变,所以冒泡排序是稳定的。
参考代码:以Java为例。
import java.util.Random; /* * 冒泡排序 */ public class BubbleSort { public static void sort(int[] a){ int n = a.length; //序列长度 for (int i = 0; i < n-1; i++){ //排序趟数 for (int j = 0; j < n-i-1; j++){ if (a[j + 1] < a[j]){ int temp = a[j]; a[j] = a[j + 1]; a[j + 1] = temp; } } } } public static void main(String[] args) { Random random = new Random(); int[] arg1 = new int[20]; for(int n=0;n<20;n++){ //从[0-100]中生成20个随机数 arg1[n] = random.nextInt(100); } System.out.println("排序前:"); for (int i = 0; i < arg1.length; i++) { System.out.print(arg1[i]+" "); } System.out.println("\\n排序后:"); long startTime = System.currentTimeMillis(); //获取开始时间 sort(arg1); long endTime = System.currentTimeMillis(); //获取结束时间 for (int i = 0; i < arg1.length; i++) { System.out.print(arg1[i]+" "); } System.out.println("\\n排序时长:"+(endTime-startTime)+"ms"); } }
运行结果:
排序前: 83 13 36 11 58 75 68 43 73 72 24 81 98 14 27 23 1 46 60 3 排序后: 1 3 11 13 14 23 24 27 36 43 46 58 60 68 72 73 75 81 83 98 排序时长:0ms
zhuanzi http://www.cnblogs.com/Y-oung/p/7820294.html
以上是关于冒泡排序算法的主要内容,如果未能解决你的问题,请参考以下文章
算法漫游指北(第七篇):冒泡排序冒泡排序算法描述动图演示代码实现过程分析时间复杂度和选择排序算法描述动图演示代码实现过程分析时间复杂度