【算法篇】八种内排序算法
常用的八种内排序算法分别是:
- 交换排序:冒泡排序、快速排序
- 选择排序:简单选择排序、堆排序
- 插入排序:直接插入排序、希尔排序
- 归并排序
- 基数排序
内排序巧记:选(选择)舰(简单选择)队(堆)的时候脚(交换)毛(冒泡)快(快速),需要把轨(归并)迹(基数)擦(插入)仔(直接插入)细(希尔)
一、算法的概念和编码实现(Java)
1、冒泡排序
冒泡排序的基本思想是,对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序
代码实现(升序)
public static void selectSort(int[] array) {int len = array.length;boolean flag = true;for (int i = 0; i < len - 1 && flag; i++) {flag = false;for (int j = 0; j < len - i - 1; j++) {if (array[j] > array[j + 1]) {int temp = array[j];array[j] = array[j + 1];array[j + 1] = temp;flag = true;}}}}
最好情况的时间复杂度 | 最坏情况的时间复杂度 | 特点 | 稳定性 |
---|---|---|---|
T(n)=O(n) | T(n)=O(n2) | 如果数据已经排序好,一次都不交换或者交换次数很少,效率很高;如果是完全逆序,则要不停的两两交换,效率很低 | 稳定 |
2、简单选择排序
简单选择排序的基本思想是,每一趟从待排序的数据元素中选择一个最小(或者最大)的元素作为首元素,直到所有元素排完为止。
代码实现(升序):
public static void selectSort(int[] array) {int len = array.length;for (int i = 0; i < len-1; i++) {int min = i;// 每趟排序默认第一个元素是最小的元素,记住下标for (int j = i + 1; j < len; j++) {// 从i+1的位置开始,依次同最小元素比较,若比最小元素小,则记住当前下标if (array[j] < array[min]) {min = j;}}// 无序区最小元素同无序区的第一个元素交换if (min != i) {int temp = array[min];array[min] = array[i];array[i] = temp;}}}
时间复杂度 | 特点 | 稳定性 |
---|---|---|
T(n)=O(n2) | 简单,相对于冒泡排序来说交换次数少 | 不稳定 |
3、直接插入排序
直接插入排序基本思想是不断将无序区的元素插入到有序区的适当位置,直到无序区没有元素排完为止
代码实现(升序):
private static void insertSort(int[] array) {for (int i = 1; i < array.length; i++) {int j ;int temp = array[i];for (j = i; j>0 && temp < array[j-1]; j--) {array[j] = array[j-1];}array[j] = temp;}}
最好情况的时间复杂度 | 最坏情况的时间复杂度 | 特点 | 稳定性 |
---|---|---|---|
T(n)=O(n) | T(n)=O(n2) | 简单 | 稳定 |
4、快速排序
对冒泡排序的一种改进,它的思想是:将元素分为两组,一组的元素比另外一组的所有元素都要小,然后再按照此方法对两组元素进行排序。
快速排序我这里就不写了,快速排序相对于前面三种排序方式来说要复杂很多,看了一些博客,发现写得都不怎么样,这里推荐一个讲快速排序的视频https://www.bilibili.com/video/av39519566/?redirectFrom=h5
附上代码实现(参考视频中的):
public static void quickSort(int[] arr,int left,int right){//如果左边索引比右边索引更大或者相等,直接使用return结束这个方法if(left >= right){return;}//定义变量保存基准数int base = arr[left];//定义变量i,指向最左边int i = left;//定义变量j,指向最右边int j = right;//当i和j不相遇的时候,在循环中进行检索while(i!=j){//先由j从右向左检索比基准数小的就停下,否则继续检索while(arr[j]>=base && i<j){j--;}//在由i从左向右检索比基准数大的就停下,否则继续检索while(arr[i]<=base && i<j){i++;}//代码走到这里,i停下了,j也停下了,然后交换i和j位置的元素int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}//交换基准数和相遇位置的元素arr[left] = arr[i];arr[i] = base;//排基准数左边的quickSort(arr,left,i-1);//排基准数右边的quickSort(arr,j+1,right);}
最好情况的时间复杂度 | 最坏情况的时间复杂度 | 平均时间复杂度 | 特点 | 稳定性 |
---|---|---|---|---|
T(n)=O(nlogn) | T(n)=O(n2) | T(n)=O(nlogn) | 较复杂 | 不稳定 |
5、希尔排序
希尔排序是对直接插入排序的优化,原理是:将数据按照步长dk分为dk个子列,然后再对每个子列运用直接插入排序。
当步长为5的时候,分组情况如下:
每个子列排好序后,变成:
代码实现(升序):
public static void main(String[] args) {int[] array = {49,38,65,97,76,13,27,49,55,4};print(array);ShellSort(array,5);print(array);ShellSort(array,3);print(array);ShellSort(array,1);print(array);}private static void print(int[] array){for (int i = 0; i < array.length; i++) {System.out.print(array[i]+"\t");}System.out.println("\n");}//希尔排序,dk表示步长private static void ShellSort(int[] array,int dk) {for(int k = 0;k<dk;k++){//每个子组做直接插入插入排序for(int i = dk+k;i<array.length;){int j ;int temp = array[i];for (j = i; j-dk>=0 && temp < array[j-dk]; ) {j -= dk;//上一个元素的索引需要减去dk,而不是减1array[j] = array[j-dk];}array[j] = temp;i += dk;//下一个元素索引加上dk,而不是加1}}}
说明:从代码层面来看,希尔排序相对于直接插入排序的不同点在于希尔排序外层多了一层循环,用来将原序列分层若干个子列。内部的直接插入排序做减减或者加加时要改成减去步长或者加上步长
二、时间复杂度和空间复杂度分析
排序的稳定性:根据关键字相同(如果数值比较的话是指大小)的记录排序前后相对位置的变化,可以分为稳定性排序算法和不稳定性排序算法。在排序的序列中,如果存在两个记录Ri和Rj,其关键字分别为Ki和Kj,并且i<=j,Ki=Kj,即记录Ri在Rj之前,排序完成后,如果记录Ri和Rj的相对位置不发生改变,那么该算法是稳定性排序,否则是不稳定排序。
排序方法 | 时间复杂度(最坏情况) | 空间复杂度(辅助空间) | 稳定性 | 复杂性 |
简单选择排序 | O(n2) | O(1) | 不稳定 | 简单 |
冒泡排序 | O(n2) | O(1) | 稳定 | 简单 |
快速排序 | O(n2) | 不稳定 | 较复杂 | |
直接插入排序 | O(n2) | O(1) | 稳定 | 简单 |
希尔排序 | O(n2) | O(1) | 不稳定 | 较复杂 |
【算法篇】八种内排序算法相关推荐
- Java 八种排序算法比较实践
写这篇文章是因为面试时经常会问这个问题,但是工作中也没用到过,所以一直是一知半解.但是我是属于比较较真的人,这次下定决心要把它们搞明白.知识在于积累,多点知识对自己总是有好处的. 我比较好奇的是,这几 ...
- ML之分类预测:基于sklearn库的七八种机器学习算法利用糖尿病(diabetes)数据集(8→1)实现二分类预测
ML之分类预测:基于sklearn库的七八种机器学习算法利用糖尿病(diabetes)数据集(8→1)实现二分类预测 目录 输出结果 数据集展示 输出结果 1.k-NN 2.LoR 4.DT 5.RF ...
- Java常用的八种排序算法与代码实现
在Java的时候,对于排序的应用需要熟练的掌握,这样才能够确保Java学习时候能够有扎实的基础能力.那Java有哪些排序算法呢?本文小千就来详细说说Java经典的8种排序算法. 经典的排序算法有八种, ...
- 八种排序算法动画讲解
思维导图 前言 算法和数据结构是一个程序员的内功,所以经常在一些笔试中都会要求手写一些简单的排序算法,以此考验面试者的编程水平!动图来源于今日头条.动图来源于今日头条.动图来源于今日头条! 1.冒泡排 ...
- 离线强化学习(Offline RL)系列3: (算法篇) IQL(Implicit Q-learning)算法详解与实现
[更新记录] 论文信息:Ilya Kostrikov, Ashvin Nair, Sergey Levine: "Offline Reinforcement Learning with Im ...
- 离线强化学习(Offline RL)系列3: (算法篇)策略约束 - BRAC算法原理详解与实现(经验篇)
论文原文:[Yifan Wu, George Tucker, Ofir Nachum: "Behavior Regularized Offline Reinforcement Learnin ...
- 离线强化学习(Offline RL)系列3: (算法篇)策略约束 - BEAR算法原理详解与实现
论文信息:Stabilizing Off-Policy Q-Learning via Bootstrapping Error Reduction 本文由UC Berkeley的Sergey Levin ...
- 归并排序改良 java_Java 八种排序算法总结
image 前言 好久没复习基础了,写个冒泡排序都要想一会.感觉自己好像老了好多,今天手痒总结一下排序算法.目前网上博客普遍都有详细介绍,写的很清楚.说实话我是没必要再写一遍的,感觉就是在啰嗦.还是重 ...
- 常见的几种内排序算法以及实现(C语言)(转)
所有未排序的数组是经过检查合法的 主要的内排序包括冒泡.插入.希尔.堆排序.归并.快速.桶排序等 其C语言实现的源文件下载地址:http://download.csdn.net/detail/mcu_ ...
最新文章
- 亚马逊专家课 | 数据体系+用户画像+商品画像系列课(立省 299 元)
- 汇编语言 把最大值放入max 把最小值放入min_Excel求最大值地球人都知道,那要求出第2、第3、第N大值呢?...
- android shell用户界面,shell界面下安装和卸载Android应用程序(apk包)
- Python 字典 values() 方法
- 2015腾讯暑期实习笔试题目
- 大学计算机应用基础考试题库,大学计算机应用基础考试题库
- linux md5 加密字符串和文件方法
- 微信web-view 开发_在不到7个月的时间里我如何成为一名Web开发人员-以及如何
- PDA连接远程SQL 2005数据库
- 论文写作课程体会和总结
- [猎豹网校]数据结构与算法_C#语言
- 如何从uboot中推算路由器flash烧写地址
- c语言单位换算转换程序,c语言时间换算(c语言时间换算过n秒)
- linux skb 存放数据,请教关于在linux网络驱动层对skb网络数据..._网络编辑_帮考网...
- 基于WEB的网上在线图书商城
- 杨柳目-杨柳科:杨柳科
- 2019阿里云峰会·北京 | 十年再出发
- Video Harmonization一些周边代码
- 苹果致力于手势再生研发,无须使用控制器即可与 ARKit 交互?
- Ubuntu20.04下的编译与运行LeGO-LOAM【问题解决】
热门文章
- tika设置文件长度限制_MySQLInnoDB某些你没注意过的限制
- xp正版验证补丁_实操web漏洞验证——IIS HTTP.sys 整数溢出漏洞
- uniapp 创建与配置 tabbar
- 组件使用中的细节点02
- 开发经验分享_06_前端开发技巧
- SpringBoot集成Flowable_Jsite待办任务菜单报500
- 企业实战_10_Mycat集成ZK实现配置同步
- 小程序开发(13)-location定位
- 计算机怎么远程桌面,电脑远程桌面如何连接 电脑远程桌面连接方法【详解】...
- 装mysql最后一步没响应_每天14点遭遇惊魂时刻,如何一步一步揪出真凶?