排序算法(一)-冒泡排序
2017-09-16 00:23
183 查看
0. 原理
临近的数字两两比较,按照从小到大或者从大到小的顺序进行交换。每一趟会将最大或者最小的数字放到最终结果的位置
重复操作直到倒数第二位
对[2, 8, 1, 5, 3]这个数组排序,完整流程如下
round 1 start 2 8 1 5 3 (exchange data: 3 <-> 5) 2 8 1 3 5 2 8 1 3 5 (exchange data: 1 <-> 8) 2 1 8 3 5 2 1 8 3 5 (exchange data: 1 <-> 2) 1 2 8 3 5 round 1 finish round 2 start 1 2 8 3 5 (exchange data: 3 <-> 8) 1 2 3 8 5 round 2 finish round 3 start 1 2 3 8 5 (exchange data: 5 <-> 8) 1 2 3 5 8 round 3 finish round 4 start round 4 finish
可见第一趟将最小的1放到了第一位
为什么叫冒泡排序呢?因为上面两两交换的过程每一趟都将最小的值放到了最顶端,很像气泡上升到顶部的过程。
1. 实现
关键代码实现如下:@Override public int[] sort(int[] data) { if (data == null || data.length <= 1) { return data; } for (int i = 0; i < data.length - 1; i++) { for (int j = data.length - 1; j > i; j--) { if (data[j] < data[j - 1]) { swap(data, j, j - 1); } } } return data; }
具体实现可查看:
GitHub/BubleSort.java
2. 复杂度分析
从代码和原理可以看出,外层循环需要n-1次,内层循环需要n-i次,比较一次,数据操作三次。因此最坏的情况应该是整个序列时逆向的,时间复杂度为O(n²),最好的情况是序列时正序的一次扫描即可,时间复杂度为O(n)。平均时间复杂度为O(n²)。由于不需要额外空间,空间复杂度为O(1)3. 优化
3.1 优化点一如果某一趟没有发生过一次交换,则说明该数组已经有序,可以直接停止循环。只要加一个标识变量就可以实现。
3.2 优化点二
使用一个标识变量记录下最后一个发生交换的位置,则可以说明前面没有发生交换的序列已经有序,所以内部循环的终结点可以用这个值来作为结束点,也就是上面代码中的i值。在内部循环结束后
i=changFlag就是这个作用。
两个优化点写入代码后如下:
@Override public int[] sort(int[] data) { if (data == null || data.length <= 1) { return data; } //标识是否已经有序 boolean isChanged; //标识最后一个发生变化的位置 int changFlag = 0; for (int i = 0; i < data.length - 1; i++) { isChanged = false; System.out.println("round " + (i + 1) + " start"); for (int j = data.length - 1; j > i; j--) { if (data[j] < data[j - 1]) { swap(data, j, j - 1); isChanged = true; changFlag = j - 1; } } //i直接设置为最后一次的交换 i = changFlag; //如果没有改变,则证明序列已经有序 if (!isChanged) { System.out.println("no exchange, break out loop"); break; } System.out.println("round " + (i + 1) + " finish"); } return data; }
具体实现可查看:
GitHub/BubleSort.java
相关文章推荐
- 排序算法之冒泡排序
- 排序算法——冒泡排序
- 选择排序,冒泡排序,排序算法实现与原理
- PHP实现排序算法----冒泡排序(Bubble Sort)
- 黑马程序员_java基础学习笔记之排序算法(选择排序、冒泡排序
- 经典排序算法-MFC实现之3:冒泡排序
- 程序员必须掌握的8种排序算法(五):冒泡排序
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序...)
- 排序算法之直接插入排序、选择排序和冒泡排序
- C#实现所有经典排序算法(选择排序,冒泡排序,快速排序,插入排序,希尔排序)
- 【排序算法】排序算法之冒泡排序
- 用JavaScript实现十大经典排序算法--冒泡排序
- 排序算法-冒泡排序
- 排序算法-------冒泡排序及其优化
- C语言中的排序算法--冒泡排序,选择排序,希尔排序
- 排序算法---冒泡排序
- 排序算法一(直接选择,堆排序,冒泡排序和快速排序)
- 排序算法之冒泡排序(C/C++)
- C#实现所有经典排序算法(选择排序 冒泡排序 快速排序)
- 排序算法-----冒泡排序和选择排序