1. 冒泡与选择排序及其比较

冒泡排序

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java如何实现分页

先阐述一下具体的思路&#xff1a; 第一步&#xff1a;编写一个分页的类里面包含了&#xff08;第一页&#xff0c;最后一页&#xff0c;下一页&#xff0c;上一页&#xff0c;当前页&#xff0c;页码等等&#xff09;对象和方法。第二步&#xff1a;进行分页的业务处理。 &g…

删除服务中的mysql服务

以管理员身份运行命令提示符&#xff0c;然后输入sc delete mysql 这里的mysql是你服务中的mysql名&#xff08;有些可能是mysql5&#xff0c;或者之类&#xff09;。

2018.09.28 hdu5435A serious math problem(数位dp)

传送门 数位dp卡常题。 写了一发dfs版本的发现过不了233。 于是赶紧转循环版本。 预处理出f数组。f[i][j]f[i][j]f[i][j]表示前i位数异或和为j的方案数。 然后每次直接数位dp就行了。 代码&#xff1a; #include<bits/stdc.h> #define mod 1000000007 #define N 100005 #…

在有原来的数据的情况下,恢复数据库的数据

只要把mysql安装目录下的data文件中的ibdata1&#xff08;储存文件的数据&#xff09;替换&#xff0c;再把你的库名的文件&#xff08;只是表结构&#xff09;加进去。

photoshop切图

1.传统切图 &#xff08;1&#xff09;打开一个psd文件&#xff0c;选择ps左边菜单栏的裁剪工具&#xff0c;选择切片工具。首先我们对这个psd文件进行分析&#xff0c;有意识的将其划分成几个选区&#xff0c;然后通过鼠标的拖拽用切片工具将我们所需要的图案切下来&#xff0…

怎么在cmd中进入D盘下的文件夹

从cmd中进入D盘&#xff0c;在光标处输入“d:”(大小写都可以)&#xff0c;按enter进入。 进入D盘根目录后&#xff0c;如果想找到work文件夹可以在光标处输入“cd work”即可。

postgresql 高可用 etcd + patroni 之六 callback bind vip

os: centos 7.4 postgresql: 9.6.9 etcd: 3.2.18 patroni: 1.4.4 本篇blog介绍下 etcd patroni 发生切换时使用 callback 来重新设定 master 的 vip。 主要是方便自有机房或托管的&#xff0c;云环境貌似不能绑定固定的vip。 patroni 的一些参数 官方文档描述在callback时又这…

${ctx} 的那些事

JSP中路径路径繁多&#xff0c;采用绝对路径&#xff0c;${pageContext.request.contextPath} 作用&#xff1a;取出部署的应用程序名&#xff0c;这样不管如何部署&#xff0c;所有路径都是正确的。 可以在jsp中定义&#xff1a; <% taglib uri”http://Java.sun.com/js…

linux文件管理 - 系统目录结构

几乎所有的计算机操作系统都是用目录结构组织文件。具体来说就是在一个目录中存放子目录和文件, 而在子目录中又会进一步存放子目录和文件&#xff0c;以此类推形成一个树状的文件结构&#xff0c;由于其结构很像一棵树的分支, 所以该结构又被称为“目录树”。 Linux系统中也沿…

JSP传值

当从点击JSP页面中的链接时&#xff0c;会执行相关操作&#xff0c;把后台所需要的参数传递过去。 最常见的是通过form表单的形式传递。如下代码所示 <s:form action"LoginAction.action" method"post"><s:textfield label"用户名" n…

nginx反向代理获取用户真实ip

nginx做反向代理时,默认的配置后端获取到的ip都是来自于nginx,如何转发用户的真实ip到后端程序呢?如是是java后端,用request.getRemoteAddr();获取到的是nginx的ip地址,而不是用户的真实ip. 修改nginx配置,如下: upstream www.xxx.com {ip_hash;server serving-server1.com:80…

Action 跳转的方法和详解

在实际项目中&#xff0c;我们难免遇到页面跳转&#xff0c;传参&#xff0c;action与action之间的跳转&#xff0c;我们这时候则需要一些方法来完成&#xff0c;如下代码所示&#xff1a; <action name"login" class"loginAction.class"><resul…

java和C++有什么异同

相同点&#xff1a; java和C都是面向对象语言&#xff0c;都使用了面向对象的基本思想&#xff08;抽象、封装、继承、多态&#xff09;&#xff0c;都具有面向对象的基本特性&#xff08;继承、组合等&#xff09;。 不同点&#xff1a; ①&#xff1a;java为解释性语言&#…

Hibernate 语句总结

关系映射数据库Hibernate使用详解&#xff1a; 在hql语句中&#xff0c;from后面接的不是表名&#xff0c;是实体名&#xff0c;from User 注&#xff1a;User是实体名&#xff0c;不是数据库中的表名。 查询并返回表中的数量&#xff1a; String sql "select count(*…

DataGrid数据绑定

后台数据绑定 用户场景是生成报表&#xff0c;展示公司各员工每个月的绩效 数据结构 包括报表和单个员工绩效两个实体 public class Report {/// <summary>/// 统计时间/// </summary>public string StatisticalDate { get; set; }public List<ReportDetail>…

String.valueOf() 和 toString的区别

当我们使用对象转换为String类型时 在使用toString()方法中&#xff0c;因为java.lang.Object类里已有public方法.toString()&#xff0c;所以对任何严格意义上的java对象都可以调用此方法。但在使用时要注意&#xff0c;必须保证object不是null值&#xff0c;否则将抛出NullP…

[转]Angular2 使用管道Pipe以及自定义管道格式数据

本文转自&#xff1a;https://www.pocketdigi.com/20170209/1563.html 管道(Pipe)可以根据开发者的意愿将数据格式化&#xff0c;还可以多个管道串联。 纯管道(Pure Pipe)与非纯管道(Impure Pipe) 管道分纯管道(Pure Pipe)和非纯管道(Impure Pipe)。默认情况下&#xff0c;管道…

解决Ajax返回的json数据乱码问题

有以下两种方式&#xff1a; 直接设置编码格式&#xff1a; response.setCharacterEncoding("utf-8");设置客户端浏览器的html的编码格式&#xff1a;response.setContentType("text/html; charsetutf-8");

BRVAH(让RecyclerView变得更高效)(1)

本文来自网易云社区作者&#xff1a;吴思博对于RecyclerView&#xff0c; 我们重复编写着那一个又一个的列表界面&#xff0c;有的要分组&#xff0c;有的要添加广告头部、有的要不同类型item排列、等等需求&#xff0c;主要代码有大部分是重复的&#xff0c;如果有一个框架能够…

校验输入的两次密码是否一致的问题

使用jQuery框架中的validate插件&#xff0c;messages为提示信息。首先导入相应的js文件。 <script src"js/jquery-1.8.2.js"></script> <script src"js/jquery.validate.min.js"></script> <script src"js/messages_zh.…