[排序算法]--冒泡排序的三种实现(Java)
2017-02-06 12:53
295 查看
冒泡排序是非常好理解的,以从小到大排序为例,每一轮排序就找出未排序序列中最大值放在最后。
设数组的长度为N:
(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
(2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。
(3)N=N-1,如果N不为0就重复前面二步,否则排序完成。
以上就是冒泡排序的基本思想,按照这个定义很快就能写出代码:
给出一个测试代码:
运行结果:
下面开始考虑优化,如果对于一个本身有序的序列,或则序列后面一大部分都是有序的序列,上面的算法就会浪费很多的时间开销,这里设置一个标志flag,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。
运行测试main函数结果:
再进一步做优化。比如,现在有一个包含1000个数的数组,仅前面100个无序,后面900个都已排好序且都大于前面100个数字,那么在第一趟遍历后,最后发生交换的位置必定小于100,且这个位置之后的数据必定已经有序了,也就是这个位置以后的数据不需要再排序了,于是记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。如果是对于上面的冒泡排序算法2来说,虽然也只排序100次,但是前面的100次排序每次都要对后面的900个数据进行比较,而对于现在的排序算法3,只需要有一次比较后面的900个数据,之后就会设置尾边界,保证后面的900个数据不再被排序。
这种方法是我看到的最优化的冒泡排序了。
运行测试例子结果:
可知运行结果正确。
本文所有代码的github地址:
https://github.com/leetcode-hust/leetcode/blob/master/louyuting/src/leetcode/Algorithm/BubbleSort.java
设数组的长度为N:
(1)比较前后相邻的二个数据,如果前面数据大于后面的数据,就将这二个数据交换。
(2)这样对数组的第0个数据到N-1个数据进行一次遍历后,最大的一个数据就“沉”到数组第N-1个位置。
(3)N=N-1,如果N不为0就重复前面二步,否则排序完成。
以上就是冒泡排序的基本思想,按照这个定义很快就能写出代码:
/** * 冒泡排序的第一种实现, 没有任何优化 * @param a * @param n */ public static void bubbleSort1(int [] a, int n){ int i, j; for(i=0; i<n; i++){//表示n次排序过程。 for(j=1; j<n-i; j++){ if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换 //交换a[j-1]和a[j] int temp; temp = a[j-1]; a[j-1] = a[j]; a[j]=temp; } } } }// end
给出一个测试代码:
public static void main(String[] args) { int[] arr = {1,1,2,0,9,3,12,7,8,3,4,65,22}; BubbleSort.bubbleSort1(arr, arr.length); for(int i:arr){ System.out.print(i+","); } }
运行结果:
0,1,1,2,3,3,4,7,8,9,12,22,65,
下面开始考虑优化,如果对于一个本身有序的序列,或则序列后面一大部分都是有序的序列,上面的算法就会浪费很多的时间开销,这里设置一个标志flag,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。
/** * 设置一个标志,如果这一趟发生了交换,则为true,否则为false。明显如果有一趟没有发生交换,说明排序已经完成。 * @param a * @param n */ public static void bubbleSort2(int [] a, int n){ int j, k = n; boolean flag = true;//发生了交换就为true, 没发生就为false,第一次判断时必须标志位true。 while (flag){ flag=false;//每次开始排序前,都设置flag为未排序过 for(j=1; j<k; j++){ if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换 //交换a[j-1]和a[j] int temp; temp = a[j-1]; a[j-1] = a[j]; a[j]=temp; //表示交换过数据; flag = true; } } k--;//减小一次排序的尾边界 }//end while }//end
运行测试main函数结果:
0,1,1,2,3,3,4,7,8,9,12,22,65,
再进一步做优化。比如,现在有一个包含1000个数的数组,仅前面100个无序,后面900个都已排好序且都大于前面100个数字,那么在第一趟遍历后,最后发生交换的位置必定小于100,且这个位置之后的数据必定已经有序了,也就是这个位置以后的数据不需要再排序了,于是记录下这位置,第二次只要从数组头部遍历到这个位置就可以了。如果是对于上面的冒泡排序算法2来说,虽然也只排序100次,但是前面的100次排序每次都要对后面的900个数据进行比较,而对于现在的排序算法3,只需要有一次比较后面的900个数据,之后就会设置尾边界,保证后面的900个数据不再被排序。
public static void bubbleSort3(int [] a, int n){ int j , k; int flag = n ;//flag来记录最后交换的位置,也就是排序的尾边界 while (flag > 0){//排序未结束标志 k = flag; //k 来记录遍历的尾边界 flag = 0; for(j=1; j<k; j++){ if(a[j-1] > a[j]){//前面的数字大于后面的数字就交换 //交换a[j-1]和a[j] int temp; temp = a[j-1]; a[j-1] = a[j]; a[j]=temp; //表示交换过数据; flag = j;//记录最新的尾边界. } } } }
这种方法是我看到的最优化的冒泡排序了。
运行测试例子结果:
0,1,1,2,3,3,4,7,8,9,12,22,65,
可知运行结果正确。
本文所有代码的github地址:
https://github.com/leetcode-hust/leetcode/blob/master/louyuting/src/leetcode/Algorithm/BubbleSort.java
相关文章推荐
- 基本排序算法——冒泡排序java实现
- 排序算法之冒泡排序——java/c++/c实现
- 排序算法— 冒泡排序的三种实现
- 【排序算法】冒泡排序原理及Java实现
- [排序算法]--直接插入排序的三种实现(Java)
- 排序算法--交换排序(冒泡排序、快速排序、随机快速排序)java实现
- 【排序算法】 冒泡排序(java实现)
- 算法 排序算法之冒泡排序(三种算法 Java实现)
- 排序算法之冒泡排序、选择排序、直接插入排序(java实现)
- #.java实现排序算法:插入排序、选择排序、冒泡排序
- java 排序算法实现 其一:冒泡排序
- 排序算法-冒泡排序的三种实现
- Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等
- java实现各种排序算法(包括冒泡排序,选择排序,插入排序,快速排序(简洁版))及性能测试
- 元素排序几种常用的排序算法的分析及java实现(希尔排序,堆排序,归并排序,快速排序,选择排序,插入排序,冒泡排序)
- 菜鸟学编程之三:三种最基本排序算法的实现(冒泡排序、选择排序、直接插入排序)
- 必须知道的八大种排序算法【java实现】(一) 冒泡排序、快速排序
- 必须知道的八大种排序算法【java实现】(一) 冒泡排序、快速排序
- 三种常用排序算法(冒泡、选择、快速)的Java实现
- java实现三种简单排序以及改良:冒泡排序,选择排序,直接插入排序