数据结构与算法---常用三大排序算法
1:冒泡排序
冒泡排序是的算法思路是将最小数值放在下标为0的位置,将最大值放在mao.length-1的位置
外层for循环开始计算层数,即mao.length-1为目标计划循环次数,当外层for完成一次后,总长度就会-1,也就是说最大值已经出来了并且放在了最后一位,那么在之后的循环中就不算这一项了,以此类推。
内层for循环从下标0开始,和下一角标比较,这里用第一项和第二项代表,如果第一项>第二项,那么两个就互换,否侧不换,然后第二项和第三项比较。直到完成这一次循环。
// 简单排序--冒泡排序int[] mao = { 120, 110, 100, 90, 80, 70, 45 };// 外循环只是循环几次for (int i = mao.length - 1; i > 1; i--) {// 内循环每循环一次就会有拍好一位,如最大值System.out.println("第" + (mao.length - i) + "次循环");for (int j = 0; j < i; j++) {if (mao[j] > mao[j + 1]) {// 如果第一个比第二大,那就换位子int temp = mao[j];mao[j] = mao[j + 1];mao[j + 1] = temp;}for (int k = 0; k < mao.length; k++) {System.out.print(mao[k] + " , ");}System.out.println();}}
第1次循环
110 , 120 , 100 , 90 , 80 , 70 , 45 ,
110 , 100 , 120 , 90 , 80 , 70 , 45 ,
110 , 100 , 90 , 120 , 80 , 70 , 45 ,
110 , 100 , 90 , 80 , 120 , 70 , 45 ,
110 , 100 , 90 , 80 , 70 , 120 , 45 ,
110 , 100 , 90 , 80 , 70 , 45 , 120 ,
第2次循环
100 , 110 , 90 , 80 , 70 , 45 , 120 ,
100 , 90 , 110 , 80 , 70 , 45 , 120 ,
100 , 90 , 80 , 110 , 70 , 45 , 120 ,
100 , 90 , 80 , 70 , 110 , 45 , 120 ,
100 , 90 , 80 , 70 , 45 , 110 , 120 ,
第3次循环
90 , 100 , 80 , 70 , 45 , 110 , 120 ,
90 , 80 , 100 , 70 , 45 , 110 , 120 ,
90 , 80 , 70 , 100 , 45 , 110 , 120 ,
90 , 80 , 70 , 45 , 100 , 110 , 120 ,
第4次循环
80 , 90 , 70 , 45 , 100 , 110 , 120 ,
80 , 70 , 90 , 45 , 100 , 110 , 120 ,
80 , 70 , 45 , 90 , 100 , 110 , 120 ,
第5次循环
70 , 80 , 45 , 90 , 100 , 110 , 120 ,
70 , 45 , 80 , 90 , 100 , 110 , 120 ,
第6次循环
45 , 70 , 80 , 90 , 100 , 110 , 120 ,
算法不变性
这里可以看出当比较到最后一次时,只剩下前两个比较了,也就是说在最右边一旦完成比较后就不会再进行任何比较操作,当然每个排序的不变性是不一样的。
冒泡排序的效率
在上面的例子结果中可以看出,7条数据的情况下,第一趟循环比较了6次,第二次比较了5次...,最后一次比较一次,公式为
(N-1)+(N-2)+(N-3)+...+1===N*(N-1)/==2====
比较算法结果:
学过高数的人都知道,数学中有叫趋向于某某某的说法,咱们的算法比较结果就是趋向于==N²/2==
。因为在N很大的情况下,N-1与N可以都看做为N,就算-1,-2也影响不大。
交换算法结果
由于在比较时不一定要交换,那么交换次数肯定是小于比较次数,有点的是从头到位都需要交换(逆向排序),则有的一次都不用换(已经排序好的),所以,这里排序算法取平均==N²/4==.
大O表示法
由于常数不算在表示法中,所以结果为O(N²)时间。
在平常的代码中,如果那你看到双重for循环时,基本就可以判断运行时间效果为O(N²)了。
2:选择排序
// 选择排序System.out.println("选择排序");int[] selectInt = { 120, 110, 100, 90, 80, 70, 45 };/*** 第一步: 原理是都和第一项(下标0)比较,小的则替换* * 外层变量设置为outer,内层变量为inner,最小数据存放下标min。* selectInt.length-1一共7个数比6次就可以了。selectInt.length内部是从下标1开始的,这里就不要再-1了,* 否侧少比较一次*/int min;for (int outer = 0; outer < selectInt.length - 1; outer++) {min = outer;// 内循环每循环一次就会有拍好一位,如最大值System.out.println("第" + (outer + 1) + "次循环");for (int inner = outer + 1; inner < selectInt.length; inner++) {// 如果后六个数中,有小于第一项(下标0)的,就调换下标if (selectInt[inner] < selectInt[min]) {min = inner;}}int temp = selectInt[outer];selectInt[outer] = selectInt[min];selectInt[min] = temp;for (int k = 0; k < selectInt.length; k++) {System.out.print(selectInt[k] + " , ");}System.out.println();}/*** 第1次循环 45 , 110 , 100 , 90 , 80 , 70 , 120 ,* */
第1次循环
45 , 110 , 100 , 90 , 80 , 70 , 120 ,
第2次循环
45 , 70 , 100 , 90 , 80 , 110 , 120 ,
第3次循环
45 , 70 , 80 , 90 , 100 , 110 , 120 ,
第4次循环
45 , 70 , 80 , 90 , 100 , 110 , 120 ,
第5次循环
45 , 70 , 80 , 90 , 100 , 110 , 120 ,
第6次循环
45 , 70 , 80 , 90 , 100 , 110 , 120 ,
选择排序算法不变性
下标小于等于outer的位置的数据总是有序的,一旦放在前面后,就不会再动。
选择排序算法效率
上面结果可以说明,虽然也是比较了和冒泡一样多的次数,但是交换缺少了很多。所以时间为N²/2
比较次数和交换次数
比较次数:N²/2
交换次数:最多N-1,最少0次,取平均N/2
大O表示法
O(N²)
以上可看出选择排序是比冒泡排序快点的。
3:插入排序
概念:有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2)
/*** 从第二项开始,第一项默认为有序 * 1:把第二项数据暂存,和第一项比较,如果第一项>第二项则调换,* 2:把第三项数据暂存,和第二项比较,如果第二项>第三项则调换, 这时调换后的第二项还要和第一项比较,然后再判断调换,从当前下标开始向左遍历凡是大于temp的数据,下标* 都均向右移动一位(调换)。* 以此类推 ........** * 很多人估计不理解为什么从第二项开始,而不是从第一项,* 这里我稍微做一下解释,插入排序就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据,算法适用于少量数据的排序,* 我们对于一个数组,不知道哪里是排序好的,可能是前三条,也可能不是有序的,我们这时就要假设一段已经排好序的数组,我们直接取前三项的话,* 不一定是排序好的, 我们取前一项的话,就一个数据肯定是排序好的,所以就从第二项开始,默认第一项已经排序好了。这就是由来。*/int insertElems[] = { 23, 4, 5, 34, 56, 21 };int inner, outer;for (outer = 1; outer < insertElems.length; outer++) {int temp = insertElems[outer];// 把第二项暂存inner = outer;// (第一项>第二项)while (inner > 0 && insertElems[inner - 1] > temp) {insertElems[inner] = insertElems[inner - 1];inner--;}insertElems[inner] = temp;for (int k = 0; k < insertElems.length; k++) {System.out.print(insertElems[k] + " , ");}System.out.println();}
4 , 23 , 5 , 34 , 56 , 21 ,
4 , 5 , 23 , 34 , 56 , 21 ,
4 , 5 , 23 , 34 , 56 , 21 ,
4 , 5 , 23 , 34 , 56 , 21 ,
4 , 5 , 21 , 23 , 34 , 56 ,
插入排序的不变性
在每趟结束时,在temp位置插入后,比outer下标小(左边)的数据项都是有序的。
结论:插入排序比冒泡快一倍,优于选择排序
转载于:https://www.cnblogs.com/cmusketeer/p/9169442.html
数据结构与算法---常用三大排序算法相关推荐
- 算法基础:常用的排序算法知识笔记
1.算法外排序分类 2.冒泡排序 冒泡排序(Bubble Sort)属于交换排序,它的原理是:循环两两比较相邻的记录,如果反序则交换,直到没有反序的记录为止. 实现算法: /** * 冒泡排序优化后的 ...
- 常用的排序算法的时间复杂度和空间复杂度
常用的排序算法的时间复杂度和空间复杂度 1.时间复杂度 (1)时间频度 一个算法执行所耗费的时间,从理论上是不能算出 ...
- java常用的排序算法的思想以及实现
一些常见的排序算法的事项以及java实现 由于时间上的原因没有计算时间复杂度,以后有时间补上,或者大家有兴趣的可以自己算算 package com.sgcc.cn;import java.util.A ...
- STL常用的排序算法
常用的排序算法 merge() sort() random_shuffle() reverse() merge() 以下是排序和通用算法:提供元素排序策略 merge: 合并两个有序序列,存放到另一个 ...
- 常用的排序算法的时间复杂度和空间复杂度 .
常用的排序算法的时间复杂度和空间复杂度 排序法 最差时间分析 平均时间复杂度 稳定度 空间复杂度 冒泡排序 O(n2) O(n2) 稳定 O(1) 快速排序 O(n2) O(n*log2n) 不稳定 ...
- php递归算法排序,php常用的排序算法代码[冒泡,递归排序-PHP源码
<script>ec(2);<script> php 常用的排序算法代码[冒泡,递归排序 冒泡排序算法 function bubblesort($arr) { $n=count ...
- 插入排序 php,常用的排序算法(二)--插入排序(PHP实现)
常用的排序算法系列 插入排序 插入排序是一种逻辑上非常好理解的排序方式,整个排序的核心就是不断在当前已经排好部分数据的数组里,找到合适的位置插入新数据.就像抓扑克牌,抓一张,然后再手里已经部分已经排好 ...
- php1到5000排序,常用的排序算法(一)--快速排序(PHP实现)
常用的排序算法系列 快速排序 假设当前需要从小到大进行排序,快速排序的核心思路是,从当前数组中,找到一个元素作为基准比较值(key),分别从两个方向进行比较.从后往前找,比key小元素放在数组前面.然 ...
- 南京邮电大学数据结构实验四(各种排序算法)
南邮数据结构实验报告四----各种排序算法 一.各类算法 (一)简单选择排序 (二)直接插入排序 (三)冒泡排序 (四)快速排序 (五)两路合并排序 (六)堆排序 二.全部排序整合+时间测试 三.算法 ...
- java语言冒泡排序法_Java实现八个常用的排序算法:插入排序、冒泡排序、选择排序、希尔排序等...
本文实现了八个常用的排序算法:插入排序.冒泡排序.选择排序.希尔排序 .快速排序.归并排序.堆排序和LST基数排序 首先是EightAlgorithms.java文件,代码如下: import jav ...
最新文章
- 转载 - sql分页优化
- Python 速度慢,试试这个方法提高 1000 倍
- ASP.NET代码对页面输出进行清理
- language wars
- spring boot 报错:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default p
- 【转】了解SQL Server触发器及触发器中的事务
- qstring去掉特定字符_如何花式、批量且操作简单地处理字符?
- git教程(二)--安装和配置git
- 搜狗输入法回应误推地震信息;近亿人在钉钉上报健康情况;Rust 1.41.0发布 | 极客头条...
- 华为OJ 初级:等差数列
- win10系统安装jdk8全过程
- linux命令大全 load,linux命令TOP参数load average详解[转]
- 【The 13th Chinese Northeast Collegiate Programming Contest】I. Temperature Survey
- 【回溯法】机器零件加工-最优加工顺序
- 想要转行成为程序员该怎么做呢?
- 开源python-向tensorflow-addons学习
- 黑马手机卫士黑名单电话拦截 使用ITelephony.aidl和NeighboringCellInfo.aidl 自动拦截黑名单电话 附文件
- Win2k3架设PPPOE服务器方法(RASPPPOE)
- 外贸开发大客户时的注意点
- get和post方式能提交数据量大小比较