交换排序之冒泡排序(java实现含优化)
2018-10-26 15:24
841 查看
冒泡排序
目录
基本思想
冒泡排序(Bubble Sort)是一种最简单的交换排序方法,它通过两两比较相邻记录的关键字,如果发生逆序,则进行交换,从而使关键字小的记录如气泡一般逐渐往上“漂浮”(左移),或者使关键字大的记录如石块一样逐渐向下“坠落”(右移)。
代码实现
代码如下:
[code]package sort; import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class BubbleSort { public static void main(String[] args) { // TODO Auto-generated method stub List<Integer> array =new ArrayList<Integer>(); Scanner input = new Scanner(System.in); System.out.println("请输入一组数字:以-1结尾"); while(input.hasNext()) { int tmp = input.nextInt(); if(tmp!=-1) { array.add(tmp); } if(tmp==-1) { long startTime = System.nanoTime(); /*冒泡排序 * 思想:每次将相邻的数做比较,大的数向下沉,每进行一轮冒泡后,需要比较的数就会减1(因为每轮都会下沉一个当前最大的数 ) */ for(int i=1;i<array.size();i++) { //n个数排序最多需要进行n-1次冒泡 for(int j=0;j<array.size()-i;j++) { //注意这里的终止条件是j<array.size()-i;因为n个数需要比较n-1次,第i轮过后剩n-i个数 if(array.get(j)>array.get(j+1)) { //大的数往下沉 int swap=array.get(j+1); array.set(j+1,array.get(j)); array.set(j, swap); } } } long endTime=System.nanoTime(); System.out.println("程序运行的时间是:"+(endTime-startTime)+"纳秒"); for(int i=0;i<array.size();i++) { System.out.print(array.get(i)+" "); } array.clear(); } } } }
执行结果如下:
时间复杂度:
需要进行n-1次排序,在每次排序过程中进行n-i次比较,所以,时间复杂度为O(n^2)。
空间复杂度:
冒泡排序只有在两个记录交换位置时,需要一个临时变量用做暂存记录,所以,空间复杂度为O(1)。
仔细阅读上述代码,会发现如果在某趟排序时,并没有记录发生交换,说明,所有记录都有序,则可以排序终止,但上述代码并没有实现这一思想,为了实现这种思想,我们只需要设置一个标记,用来检测每趟排序过程中是否会发生交换即可。
修改后的代码如下:
[code] for(int i=1;i<array.size();i++) { //n个数排序最多需要进行n-1次冒泡 boolean flag=false; for(int j=0;j<array.size()-i;j++) { //注意这里的终止条件是j<array.size()-i;因为n个数需要比较n-1次,第i轮过后剩n-i个数 if(array.get(j)>array.get(j+1)) { //大的数往下沉 int swap=array.get(j+1); array.set(j+1,array.get(j)); array.set(j, swap); flag=true; } } if(!flag) //如果某趟冒泡中没有进行交换,跳出循环 break; }
再次运行程序:
我们发现,运行时间变短了,当然,这种优化只存在某趟冒泡没有发生记录的交换才起作用,如果初始记录序列逆序,则必须进行n-1趟排序,因此时间复杂度仍为O(n^2)。
还可不可以继续进行优化,答案是肯定的,之前实现的代码,都是每趟冒泡将最大的右移(即单向冒泡),我们可以在每趟排序时,进行双向冒泡,即把最大的放在最右边后,再把最小的放在最左边,这样n个记录最多需要n/2趟排序,修改代码如下:
[code]for(int i=1;i<array.size()/2;i++) { //n个数排序最多需要进行n-1次冒泡 boolean flag=false; for(int j=0;j<array.size()-i;j++) { //注意这里的终止条件是j<array.size()-i;因为n个数需要比较n-1次,第i轮过后剩n-i个数 if(array.get(j)>array.get(j+1)) { //大的数往下沉 int swap=array.get(j+1); array.set(j+1,array.get(j)); array.set(j, swap); flag=true; } } for(int j=array.size()-i-1;j>0;j--) { if(array.get(j)<array.get(j-1)) { //小的数往上浮 int swap=array.get(j-1); array.set(j-1,array.get(j)); array.set(j, swap); flag=true; } } if(!flag) //如果某趟冒泡中没有进行交换,跳出循环 break; }
再次运行程序:
至于这里显示程序的时间,为什么会增加,我也不知道,楼主弱鸡一枚,我每次运行相同的数据,它都显示不一样。尴尬!!!
这种实现也不会改变冒泡排序的时间复杂度,时间复杂度仍为O(n^2)。
阅读更多
相关文章推荐
- java实现交换排序之冒泡排序
- 交换排序之冒泡排序(java实现)
- Java实现交换排序 之 冒泡排序和快速排序
- 【LintCode-463】整数排序(Java实现-冒泡排序优化)
- java实现排序算法之交换排序(冒泡排序和快速排序)
- Java分别实现冒泡排序、插入排序、快速排序、选择排序、交换排序
- 排序算法--交换排序(冒泡排序、快速排序、随机快速排序)java实现
- 交换排序------冒泡排序(实现Java)
- java版排序算法简介及冒泡排序以及优化,选择排序,直接插入排序,希尔排序,堆排序,快速排序及其优化前言 2 分类 2 稳定性 3 时间复杂度 4 Java实现版本 5 1、冒泡排序 6 2、选择排序
- java实现选择排序和冒泡排序
- JavaSE第三十五讲:冒泡排序、交换排序及快速排序原理与实现
- 冒泡排序、选择排序、直接插入排序(java实现)
- java 实现 冒泡排序、选择排序、插入排序。
- java编程排序之内置引用类型的排序规则实现,和自定义规则实现+冒泡排序运用
- 程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
- java实现交换排序
- java实现交换排序
- java实现冒泡排序,选择排序,插入排序,快速排序(简洁版)及性能测试
- java交换排序之鸡尾酒排序实现方法
- java实现的选择排序、冒泡排序、二分查找