冒泡排序

1. 思想

  冒泡排序(Bubble Sort)是一种交换排序,基本思路是:两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止。

2. 实现

2.1 初学常用的一种

public static <T extends Comparable<? super T>> void BubbleSort(T[] a) {int length = a.length;for (int i = 0; i < length; i++) {for (int j = i+1; j < length; j++) {if (a[i].compareTo(a[j]) > 0) {Object obj = a[i];a[j] = a[i];a[i] = (T)obj;} // end if} // end for} // end for
} // end BubbleSort

  缺陷:每一次内循环结束时,对其余的关键字没有帮助,甚至把原来靠近正确排序位置的记录交换到较远的地方。即,算法是低效的。

2.2 正宗的冒泡排序

public static <T extends Comparable<? super T>> void BubbleSort(T[] a) {int length = a.length;for (int i = 0; i < length - 1; i++) {for (int j = length - 2; j >= i; j--) {if (a[j].compareTo(a[j+1]) > 0) {Object obj = a[i];a[i] = a[j];a[j] = (T)obj;} // end if} // end for} // end for
} // end BubbleSort

  

  显然这一算法比之前的实现要有效,图中较小的数字如同气泡慢慢浮到上面,因此将此算法命名为冒泡排序。

2.3 冒泡排序的优化

  对于已经有序或接近有序的集合时,会进行很多次不必要的循环比较,为此,需要改进实现,设置一个flag记录在一次循环比较中是否有交换操作,如果没有说明集合已经有序。

public static <T extends Comparable<? super T>> void BubbleSort(T[] a) {int length = a.length;boolean flag = true;  // 用flag作为标记for (int i = 0; (i < length - 1) && flag; i++) {flag = false;for (int j = length - 2; j >= i; j--) {if (a[j].compareTo(a[j+1]) > 0) {Object obj = a[i];a[i] = a[j];a[j] = (T)obj;flag = true;     // 有数据交换则为true} // end if} // end for} // end for
} // end BubbleSort

2.4 冒泡排序复杂度分析

  最好的情况下,也就是数组有序时,根据最后改进的代码,需要比较n-1次关键字,没有数据交换,时间复杂度为O(n)。最坏的情况下,即待排序记录全为倒序,此时比较1+2+3+4+…+(n-1) = n(n-1)/2次,并作等数量级的记录移动。所以时间复杂度为O(n2)。

简单选择排序

1. 思想

  冒泡排序的思想就不断地在交换,通过交换完成最终的排序。这种方式太繁琐,可不可以在确定位置的时候在交换,减少交换操作,完成只交换一次就完成相应关键字的排序定位?这就是选择排序的初步思想。

2. 排序算法

  简单选择排序(Simple Selection Sort)就是通过n-i次关键字间的比较,从n-i+1个记录中选出关键字最小的记录,并和第i(1 ≤ i ≤ n)个记录交换。

// simple selection sort
public static <T extends Comparable<? super T>> void SelectSort(T[] a) {int length = a.length;for (int i = 0; i < length - 1; i++) {int min = i;for (int j = i+1; j < length; j++) {if (a[min].compareTo(a[j]) > 0) {min = j;} // end if} // end forif (i != min) {Object obj = a[min];a[min] = a[i];a[i] = (T)obj;} // end if} // end for
} // end SelectSort

3. 简单选择排序复杂度分析

  从简单选择排序过程看,最大的特点是减少了移动数据的次数,这样节约了时间。无论最好还是最差的情况下,比较次数都是一样的,第i趟要比较n-i次关键字,共需要比较(n-1)+(n-2)+…+2+1=n(n-1)/2次,最好情况下,即有序时,交换0次,最坏情况下,即逆序时,交换n-1次。最终排序时间为比较和移动的总和,时间复杂度为O(n2)。

尽管与冒泡排序同为O(n2),但简单选择排序的性能还是要略优于冒泡排序。(下列比较缺不是!)

冒泡与选择排序对比

import java.util.Arrays;
/*** sort for Array* @author Administrator*/
public class Sort {// 非标准的冒泡排序,最简单的交换排序!(让每一个关键字,都和它后面的每一个关键字比较,如果大则交换)public static void BubbleSort1(int[] a) {int length = a.length;for (int i = 0; i < length; i++) {for (int j = i+1; j < length; j++) {if (a[i] > a[j]) {int obj = a[i];a[i] = a[j];a[j] = obj;} // end if} // end for} // end for} // end BubbleSort//  标准冒泡排序public static void BubbleSort2(int[] a) {int length = a.length;for (int i = 0; i < length - 1; i++) {for (int j = length - 2; j >= i; j--) {if (a[j] > a[j+1]) {int obj = a[j];a[j] = a[j+1];a[j+1] = obj;} // end if} // end for} // end for} // end BubbleSortpublic static void BubbleSort3(int[] a) {int length = a.length;boolean flag = true;  // 用flag作为标记for (int i = 0; (i < length - 1) && flag; i++) {flag = false;for (int j = length - 2; j >= i; j--) {if (a[j] > a[j+1]) {int obj = a[j];a[j] = a[j+1];a[j+1] = obj;flag = true;     // 有数据交换则为true} // end if} // end for} // end for} // end BubbleSort// simple selection sortpublic static void SelectSort(int[] a) {int length = a.length;for (int i = 0; i < length - 1; i++) {int min = i;for (int j = i+1; j < length; j++) {if (a[min] > a[j]) {min = j;} // end if} // end forif (i != min) {int obj = a[min];a[min] = a[i];a[i] = obj;} // end if} // end for} // end SelectSortpublic static void main(String[] args) {// 随机生成50000、50_0000的整数int[] a = new int[50_0000];for (int i = 0; i < a.length; i++) {a[i] = (int)(Math.random() * 500);//System.out.print(a[i] + " ");}// System.out.println();// 保证各个排序算法使用的数据一样int[] a2 = Arrays.copyOf(a, a.length);int[] a3 = Arrays.copyOf(a, a.length);int[] a4 = Arrays.copyOf(a, a.length);Date d1 = new Date();BubbleSort1(a);    // 最常用的初学实现       50000:919,962,1032   500000:59425,60701,59811System.out.println(new Date().getTime() - d1.getTime());Date d2 = new Date();BubbleSort2(a2);   // 标准冒泡           50000:5332,5300,5957    500000:491104,480838,478621System.out.println(new Date().getTime() - d2.getTime());Date d3 = new Date();BubbleSort3(a3);   // 改进冒泡       50000: 5477,5648,5696     500000:526451,522458,503981System.out.println(new Date().getTime() - d3.getTime());Date d4 = new Date();SelectSort(a4);      //  50000: 1118,1256,1076    500000:107144,95680,94796System.out.println(new Date().getTime() - d4.getTime());}
} // end Sort

  可以看出对于随机数组,常用的冒泡性能最好,接下来是简单选择排序,标准冒泡和改进的冒泡效率不如初学常用的冒泡高。改进的冒泡排序适合于接近有序或已经有序的情况。

转载于:https://www.cnblogs.com/datamining-bio/p/9715774.html

1. 冒泡与选择排序及其比较相关推荐

  1. C语言冒泡法和选择排序法

    C语言冒泡法和选择排序法 1.冒泡法代码 #include<stdio.h> int main() {int a[3];int p,i,tmp;for(i=0;i<3;i++)sca ...

  2. python基础:冒泡和选择排序算法实现

    冒泡排序和选择排序 首先引用一下百度百科对于冒泡算法的定义: 冒泡排序算法的原理如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一 ...

  3. php冒泡和选择排序,选择排序vs冒泡排序

    冒泡排序: 稳定算法,发挥的也很稳定,最小时间复杂度n,最差复杂度为 n^2,使用两层循环实现,依次将数组里的每个元素,与其他元素比较,只要大于当前正在比的元素就交换两者 代码实现:function  ...

  4. php冒泡 插入选择 排序,说说PHP数组的三种排序(冒泡/选择/插入)方法

    说说PHP数组的三种排序(冒泡/选择/插入)方法 PHP #数组 #排序 #冒泡 #选择 #插入2012-05-30 10:17 一.冒泡排序法 说明:找到最大的数,排列到最后面,然后继续找 例: $ ...

  5. 最少交换次数python_史上最简单!冒泡、选择排序的Python实现及算法优化详解

    1.排序概念 内部排序和外部排序 根据排序过程中,待排序的数据是否全部被放在内存中,分为两大类: 内部排序:指的是待排序的数据存放在计算机内存中进行的排序过程: 外部排序:指的是排序中要对外存储器进行 ...

  6. 张仰彪第二排序法_十大排序之冒泡和选择排序

    你好,我是goldsunC 让我们一起进步吧! 排序 所谓排序,就是指将一组数据,按照特定规则调换位置,使数据具有某种顺序关系(递增或递减).在排序过程中,数据的移动方式可分为直接移动和逻辑移动两种. ...

  7. 算法基础——冒泡与选择排序

    冒泡排序: 一种交换排序,两两比较相邻记录的关键字,如果反序则交换,直到没有反序的记录为止. 例如4个数排序 #include<stdio.h> int main() { int ar[5 ...

  8. 水冒泡了几度_冒泡和选择排序详解

    排序 所谓排序,就是指将一组数据,按照特定规则调换位置,使数据具有某种顺序关系(递增或递减). 在排序过程中,数据的移动方式可分为直接移动和逻辑移动两种.直接移动是直接交换存储数据的位置,而逻辑移动并 ...

  9. 哈佛大学公开课:计算机科学cs50 学习笔记及代码练习(第8集:冒泡,选择排序,递归)

    0. 前言 这门课讲的排序相当清楚,老师用很容易懂的方式讲原理,代码部分在linux下写,用gdb调试,这才是编程的学习方法.记得以前国内本科也学过,但根本没讲清楚.现在研究生又听这门公开课,发现把原 ...

最新文章

  1. js插件 webp_(转)让浏览器支持Webp
  2. CentOS7攻克日记(三) —— 安装Python3.6
  3. app启动流程:冷启动,热启动,暖启动
  4. 文件目录遍历的并发算法
  5. On Tutorial with Caffe--a Hands DIY DL for Vision
  6. KXMovie基于ffmpeg的播放器
  7. db2 获取返回的游标_MySQL ------ 存储过程与游标简单使用
  8. cmds在线重定义增加列
  9. Express是Node.js上最流行的Web开发框架。
  10. android 字体点击变色,Android TextView 中实现部分文字变色以及点击事件
  11. 为什么html中图片显示不出来,网页图片显示不出来是什么原因?
  12. php 触摸键盘,window_Win10正式版新增键盘快捷键和触摸手势汇总篇,  微软在新一代操作系统Win1 - phpStudy...
  13. mvn help:system下载包失败解决
  14. 电脑桌面云便签怎么绑定和开启微信提醒?
  15. [flink]各种大厂开源案例
  16. 【开源项目】电视盒子好用又强大的APP: TVRemoteIME
  17. arx开发版本对照表
  18. 深度学习理论与实践第二章作业-FNN手写数字识别
  19. 免费的 PPT 模版资源
  20. 多卡聚合智能融合通信设备在智慧房车上的应用

热门文章

  1. linux转mysql_[转] linux下安装mysql服务器
  2. Android adb 启动APP
  3. 王者荣耀4月14日服务器维护,王者荣耀体验服4月14日停机更新 鲁班七号加强!...
  4. c++代码根据点位连线_邹军:数控车倒角C与自动倒圆角R编程方法
  5. markdown改字体和背景颜色(html)
  6. 根据大小分割大文本_场景文本检测—CTPN算法介绍
  7. mysql加锁后怎么解除_Mysql查看死锁与解除死锁的深入讲解
  8. HTML+CSS+JS实现 ❤️九宫格图片悬停遮罩层特效❤️
  9. HTML+CSS+JS实现 ❤️echarts省市区地图城市选择❤️
  10. php设置表单为整数,PHP中如何判断FROM表单提交的数字是否为整数?