交换排序(冒泡、快速)
冒泡排序
排序策略
相邻的两个元素的关键字进行比较,小的元素向上冒,大的元素向下沉
排序过程
以集合{49, 38, 65, 97, 76, 13, 27, 49}中数据为例,执行一趟冒泡排序
①比较49、38(执行交换)
②比较49、65
③比较65、97
④比较97、76(执行交换)
⑤比较97、13(执行交换)
⑥比较97、27(执行交换)
⑦比较97、49(执行交换)
可以发现,已经将集合中最大的数97排到了尾部、所以对于含有n个数据的列表只需执行n-1次,就能完成排序
实现代码
/*** 冒泡排序* @param list 需要排序的行列* @return 排序结果*/public static int[] bubSort(int[] list) {//交换值int temp = 0;//循环处理(第一层循环为执行的趟数,第二层循环为比较数据、交换)for(int i = 0; i < list.length-1; i++) {for(int j = 0; j <list.length-1-i; j++) {if(list[j] > list[j+1]) {temp = list[j+1];list[j+1] = list[j];list[j] = temp;}}} return list;}
测试结果
时间及空间复杂度
①时间
最好,原先序列为正序:比较次数n-1(1趟)、移动次数0
最坏,原先序列为倒序:比较次数即(n*(n-1))/2、移动次数即(3*n*(n-1))/2(每次执行三次交换操作)
即平均时间复杂度为:T(n)=O(n2)
②空间
S(n)=O(1)
③稳定性
由于是两个相邻的数据比较、交换,所以是稳定的
适用范围
① n较小
②局部有序
③在n个待排序的数据中选择前k(k<<n时)个最大值(只需执行n趟)
快速排序
排序策略
任选一个元素的关键字(一般为key[0])作为标准,将序列分成两部分。其中左半部分的结点的关键字小于等于该元素的关键字,右半部分的结点的关键字大于等于该元素的关键字。然后, 对左右两部分分别进行类似的处理,直至排好序为止
排序过程
以集合{49, 38, 65, 97, 76, 13, 27, 49}中数据为例,执行一趟快速排序
①取出索引为0的数据(49),设置i、j指针指向头和尾
②从j
开始,判断**(list[j] = 49) = 49**,则移动j指针(j- -)
③从j
开始,判断**(list[j] = 27) < 49**,则将27放置于i处
④从i
开始,判断**(list[j] = 38) < 49**,则移动i指针(i++)
⑤从i
开始,判断**(list[j] = 65) > 49**,则将65放置于j处
⑥从j
开始,判断**(list[j] = 13) < 49**,则将13放置于i处
⑦从i
开始,判断**(list[j] = 97) > 49**,则将97放置于j处
⑧从j
开始,判断**(list[j] = 49) = 49**,则移动j指针(j- -)
⑨此时i
=j
,将49插入其中
然后可对49两边的数据分别进行排序,类似于二叉树向下扩展,每一个点都会扩展出两个子点,借助于二分查找的思想,一层接一层,直至排序结束
实现代码
一次排序执行代码:
/*** 一次快速排序* @param list 需要排序的行列* @param i 头指针* @param j 尾指针* @return 拍寻结束中间指针*/public static int onceQuiSort(int[] list, int i, int j) {//取出第一位元素作为界点int point = list[i];while(i != j) {//由于表头元素为界点,界点已经被取出,此时表头可存储数据,则先从表尾开始//此处使用>=和<=判断,以免出现重复数据导致死循环while(i != j && list[j] >= point) {//表尾数据大于界点,移动指针j--;}//否则,将较小值放在界点前list[i] = list[j];//再从表头开始while(i != j && list[i] <= point) {//表头数据小于界点,移动指针i++;}//否则,将较小值放在界点之后list[j] = list[i];}//将界点放于表中list[i] = point; return i;}
类似于二叉树的遍历,使用递归来进行整体排序:
/*** 快速排序* @param list 需要排序的行列* @param i 数据开始索引* @param j 数据结束索引* @return 排序的结果*/public static int[] quiSort(int[] list, int i, int j) {//长度大于一时,使用递归进行排序(相当于一个二叉树)if(i < j) {int mid = onceQuiSort(list, i, j);System.out.println(Arrays.toString(list));//左边排序,需使得mid-1,不然会死循环quiSort(list, i, mid-1);//右边排序quiSort(list, mid+1, j);}return list;}
测试结果
时间及空间复杂度
①时间
对于第一次排序(将所有数据都排序),i
与j
从两边移动到中间,若只考虑判断,为O(n)
而主排序方法由于使二分法,类似于二叉树
最好,每次选中的界点排序后都位于中心位置,即二叉树为完全二叉树,这时树有log2n层
最坏,每次选中的界点排序后都位于边缘位置,即二叉树为最坏的二叉树,每个结点只有一个孩子,这时树有n-1层
对于每一层虽然分为了很多个部分,但结合起来相当于将所有数据都排序
则,最优:T(n) = O(n*log2n)
最差:T(n) = O(n2)
即平均时间复杂度为:T(n) = O(n*log2n)
②空间
由于使用了一个递归,对于中间值mid的存储需要一个栈
最优:S(n) = O(log2n)
最差:S(n) = O(n)
即平均空间复杂度为:T(n) = O(log2n)
③稳定性
该方法是与界点进行比较,并将左端大于界点的记录移至右端,将右端小于的记录移至左端,所以在移动过中,原两个相同大小的记录的位置会有变化。即该排序方法是一种不稳定的排序方法。
适用范围
①n较大且表无序时
②选取第k(1<=k<=n)个元素时(只需让k成为界点,执行一次快速排序)
交换排序(冒泡、快速)相关推荐
- C++实现各种交换排序(冒泡,快速)
冒泡排序: 代码如下: #include <iostream> using namespace std;void BubbleSort(int *a, int len) {//数组下标从0 ...
- 排序及查找----[(冒泡,快速)(拉格朗日,二分)]
代码展示: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; ...
- Python - 排序( 插入, 冒泡, 快速, 二分 )
插入排序 算法分析 两次循环, 大循环对队列中的每一个元素拿出来作为小循环的裁定对象 小循环对堆当前循环对象在有序队列中寻找插入的位置 性能参数 空间复杂度 O(1) 时间复杂度 O(n^2) 详细代 ...
- 从春招到秋招,一个本科生的求职之路
下面是我的一个一万多字的c++笔面试总结,包含数据库,计网,操作系统,算法,数据结构,设计模式和c++等多方面的笔面试总结,有的是提纲,大部分都展开详细有描述了,可能有错误,看的时候小心查证. 数据库 ...
- [转载]从春招到秋招,一个本科生的求职之路。
原文:从春招到秋招,一个本科生的求职之路. 自报家门,北理工软件学院本科生. 主要部分: 1.毕业去向选择 2.春招过程 3.暑期实习 4.秋招辛酸路程 5.一点感悟 1.毕业去向选择问题 从大一开始 ...
- [PHP] 2018年终总结
去掉敏感信息后的不完整版 ========================================================================== 2018年12月29日 ...
- [日常] 面试知识点总结(持续更新)
数据结构和算法:物理结构和逻辑结构1.逻辑结构(集合结构,线性结构,树形结构,图形结构)2.物理结构一般是讲内存,顺序存储结构,链式存储结构浅谈算法中,高斯算法从1加到100,循环的话是100次,高斯 ...
- 八大排序算法java_java实现八大排序算法
Arrays.sort() 采用了2种排序算法 -- 基本类型数据使用快速排序法,对象数组使用归并排序. java的Collections.sort算法调用的是归并排序,它是稳定排序 方法一:直接插入 ...
- java史努比_Java八大排序
Arrays.sort() 采用了2种排序算法 -- 基本类型数据使用快速排序法,对象数组使用归并排序. java的Collections.sort算法调用的是归并排序,它是稳定排序 方法一:直接插入 ...
- (第20讲)关于排序的各种算法的汇总的题目
1.排序算法的稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前 ...
最新文章
- Opencv 去高光或镜面反射(illuminationChange)
- php多图片上传并回显,如何用input标签和jquery实现多图片的上传和回显功能
- python输入n×n的矩阵0和1_关于Python数组和矩阵的用法X[:,0]、X[:,1]、X[:,:,0]、X[:,:,1]、X[:,m:n]和X[:,:,m:n]...
- android opengl版本太低,Android OpenGL:可能内存不足?
- 如何才能打造一个良好的Java功底,提高自己的核心竞争力?
- jenkins没有参数化构建过程选项
- python基础_collections系列
- python程序员年薪20万_据说做好这几道考题的python程序员年薪超20万
- Beginning WF 4.0翻译——第一章(创建一个简单的工作流)续二
- 计算SRTM的高程异常的参考
- 计算机网络-3-局域网数据链路层原理与技术
- 启明云端分享|IDO-SOM3022-V1.0:可适用于物联网等多个领域
- jq 下拉列表选中事件_JQuery select各种事件
- 互联网创业公司的管理
- 孙陶然:成功者都不找借口
- 字符串算法:从入门到劝退
- 【清明特辑】那些虽败犹荣的科技先烈们
- JAVA日记之SpringJdbcTemplate/声明式事务控制 ----喝最烈的酒.
- QQ红包终于支持微信支付了
- 榆熙电商:商家如何做好店铺运营?
热门文章
- ERROR: Unrecognized command line argument: #39;use#39;
- rpm | 升级软件包
- [UWP]用画中画模式(CompactOverlay Mode)让用总在最前端显示
- 使用^、(异或、并且)位运算 实现算数加法(+)
- 二进制搜索树_数据结构101:二进制搜索树
- 研发团队绩效_如何在团队内部建立网络绩效文化
- 计算机编程课程顺序_620多个免费的在线编程和计算机科学课程,您可以在三月开始
- 120_PowerBI堆积瀑布图_R脚本Visual
- python经典书 豆瓣_入门,,豆瓣高分推荐的Python书籍
- 第二章 获取变量的相关统计指标