算法章节 递归、排序、⼆分查找
递归
概念与特性 | 函数调⽤函数⾃身的编程⽅式叫做递归,调⽤为”递“,返回为”归“ |
三个条件 |
1. ⼀个问题的解可以分解为多个⼦问题的解; 2. 分解之后的⼦问题,除了数据规模不同,求解思路跟原问题相同; 3. 存在递归终⽌条件; |
编程技巧 |
1. 寻找将⼤问题分解为⼩问题求解的规律; 2. 找出递推公式和终⽌条件,将其直接翻译成代码; 3. 切记不要⼈⾁⼀层⼀层的递归; 换句话说,也就是:如果⼀个问题A可以分解为若⼲⼦问题B、C、D,我们可以假设⼦问题B、C、D已经解决,在此基础上思考如何解决问题A。 我们只需要思考问题A与⼦问题B、C、D两层之间的关系即可,不需要⼀层⼀层往下思考⼦问题与⼦⼦问题,⼦⼦问题与⼦⼦⼦问题之间的关系。 |
应⽤场景 |
递归是⼀种应⽤⾮常⼴泛编程技巧,很多数据结构和算法的编码实现都要 ⽤到递归,⽐如快排、归并排序、DFS(深度优先搜索算法)、⼆叉树遍历、回溯等; |
其他知识点 |
1. 避免堆栈溢出(限制调⽤层次;递归改为迭代;尾递归优化); 2. 避免重复计算(利⽤备忘录); |
掌握程度 |
1. 熟练编写斐波那契数列、全排列、⼋皇后、快速排序;归并排序、DFS、⼆叉树遍历、链表反转递归实现等; |
排序
概念与特性 |
1. 稳定性:如果待排序的序列中存在值相等的元素,经过排序之后,相等元素之间原有的先后顺序不变; 2. 原地:不额外申请⾮常量级的空间来临时存储排序数据;原地排序算法并不⼀定空间复杂度是O(1),空间复杂度是O(1)的排序算法⼀定是原地排序算法,⽐如快速排序是原地排序算法,但因为⽤到递归,函数调⽤栈会消耗⾮常量级的空间,所以,空间复杂度并⾮O(1),是O(logn)。 |
|
O(n^2) | 冒泡排序 | 冒泡排序是稳定原地排序算法。 整个冒泡排序过程包含多遍冒泡操作。每次冒泡操作都会遍历整个数组,依次对相邻的元素进⾏⽐较,看是否满⾜⼤⼩关系要求,如果不满⾜,就将它们互换位置。⼀次冒泡操作会让⾄少⼀个元素移动到它应该在的位置,重复n次,就完成了n个数据的 排序⼯作。 |
插⼊排序 | 插⼊排序是稳定原地排序算法。⾸先,我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有⼀个元素,就是数组中的第⼀个元素。插⼊算法的核⼼思想是取未排序区间中的元素,在已排序区间中找到合适的插⼊位置将其插⼊,并保证已排序区间数据⼀直有序。重复这个过程,直到未排序区间中元素为空,算法结束。 | |
选择排序 |
选择排序算法是⾮稳定原地排序算法。其实现思路有点类似插⼊排序,也分已排序区间和未排序区间。 但不同点在于,选择排序算法每次会从未排序区间中,找到最⼩ 的元素,将其放到已排序区间的末尾。 |
|
O(nlogn) | 快速排序 |
快速排序是⾮稳定原地排序算法。空间复杂度是O(logn)。 如果要排序数组中下标从p到r之间的⼀组数据,我们选择p到r之 间的任意⼀个数据作为pivot(分区点),然后,遍历p到r之间 的数据,将⼩于pivot的放到左边,将⼤于pivot的放到右边,将 pivot放到中间。经过这⼀步骤之后,p到r之间的数据就被分成 了三个部分。假设pivot现在所在位置的下标是q,那p到q-1之 间数据都⼩于pivot,中间是pivot,q+1到r之间的数据都⼤于 pivot。根据分治、递归的处理思想,我们递归排序下标从p到 q-1之间的数据和下标从q+1到r之间的数据,直到区间缩⼩为 1,就说明所有的数据都有序了。 递推公式:quickSort(p…r)=quickSort(p…q-1) & quickSort(q+1…r) |
归并排序 | 归并排序是稳定⾮原地排序算法。空间复杂度是O(n)。 如果要排序⼀个数组,我们先把数组从中间分成前后两部分,然后,对前后两部分分别排序,再将排好序的两部分合并在⼀起,这样整个数组就都有序了。递推公式:mergeSort(p…r)=merge(mergeSort(p…q), mergeSort(q+1… r)) | |
O(n) | 桶排序 | 桶排序,顾名思义,会⽤到“桶”,核⼼思想是将要排序的数据分到⼏个有序的桶⾥,每个桶⾥的数据再单独进⾏排序。桶内排完序之后,再把每个桶⾥的数据按照顺序依次取出,组成的序列就是有序的了。要排序的数据需要很容易就能划分成m个桶,并且,桶与桶之间 有着天然的⼤⼩顺序。这样每个桶内的数据都排完序之后,桶与桶之间的数据不需要再进⾏排序。 |
计数排序 |
实际上,计数排序是桶排序的⼀种特殊情况。当要排序的n个数据,所处的范围并不⼤的时候,⽐如最⼤值是k,我们就可以把数据划分成k个桶。每个桶内的数据值都是相同的,省掉了桶内排序的时间。 |
|
基数排序 | 基数排序对要排序的数据也是有要求的,需要可以分割出独⽴的“位”来⽐较,⽽且位之间有递进的关系:如果a数据的⾼位⽐ b数据⼤,那剩下的低位就不⽤⽐了。除此之外,每⼀位的数 据范围不能太⼤,可以使⽤其他线性排序算法来排序,否则,基数排序的时间复杂度就⽆法做到O(n)了。 | |
应⽤场景 | ⼯程中的排序函数⼀般使⽤O(nlogn)的快排、归并或者堆排序作为主排序算 法,当数据规模较⼩时,转⽽选择使⽤更加简单的插⼊排序。 | |
其他知识点 |
为了避免快速排序时间复杂度退化为极端情况O(n^2),我们使⽤更加⾼级的 分区点选择⽅式,⽐如三数取中法、随机法等。 |
|
掌握程度 |
1. 熟练掌握冒泡、插⼊、选择、快速、归并排序的原理、代码实现; 2. 熟练掌握快速、归并排序的时间和空间复杂度分析; 3. 掌握桶排序、计数排序、基数排序的原理 |
⼆分查找
概念与特性 | ⼆分查找针对的是⼀个有序的数据集合,查找思想有点类似分治思想。每次都通过跟区间的中间元素对⽐,将待查找的区间缩⼩为之前的⼀半,直到找到要查找的元素,或者区间被缩⼩为0。 |
操作与复杂度 | ⼆分查找的时间复杂度是O(logn) |
⼆分查找变体 |
变体⼀:查找第⼀个值等于给定值的元素 变体⼆:查找最后⼀个值等于给定值的元素 变体三:查找第⼀个⼤于等于给定值的元素 变体四:查找最后⼀个⼩于等于给定值的元素 |
掌握程度 | 熟练掌握⼆分查找、⼆分查找变体的代码实现 |
相关图片
参考链接
- 菜鸟教程
算法章节 递归、排序、⼆分查找相关推荐
- Python 算法:递归 排序 查找
一.算法概念 算法:就是一个计算过程,解决问题的方法. 二.递归 2.1.递归特点 递归算法是一种直接或间接调用自身算法的过程,在计算机编程中,它往往使算法的描述简洁而且易于理解. 递归算法解决问题的 ...
- 算法与数据结构 -- 排序和查找(五)
一.排序算法 冒泡排序 选择排序 插入排序 希尔排序 快速排序 归并排序 堆排序 桶排序 二.算法实现 冒泡排序 每次比较相邻两个元素,若不符合大小关系,则交换元素位置.让最小的(或最大)元素在列表尾 ...
- 折半查找递归算法_两篇文章带你了解java基础算法之递归和折半查找
2.1 递归 递归(recursion)是一种常见的解决问题的方法,即把问题逐渐简单化.递归的基本思想就是"自己调用自己",一个使用递归技术的方法将会直接或者间接的调用自己.利用递 ...
- java 递归_两篇文章带你了解java基础算法之递归和折半查找
2.1 递归 递归(recursion)是一种常见的解决问题的方法,即把问题逐渐简单化.递归的基本思想就是"自己调用自己",一个使用递归技术的方法将会直接或者间接的调用自己.利用递 ...
- 翻手算法php,PHP各种常见经典算法总结【排序、查找、翻转等】
本文实例讲述了php各种常见经典算法.分享给大家供大家参考,具体如下: 冒泡排序算法 public function test() { $arr = array(43, 54, 62, 21, 66, ...
- 【数据结构与算法】task3 排序二分查找
排序 参考:https://github.com/wangzheng0822/algo/tree/master/python 归并排序 def merge_sort(a):_merge_sort_be ...
- 算法小抄6-二分查找
二分查找,又名折半查找,其搜索过程如下: 从数组中间的元素开始,如果元素刚好是要查找的元素,则搜索过程结束 如果搜索元素大于或小于中间元素,则排除掉不符合条件的那一半元素,在剩下的数组中进行查找 由于 ...
- 散列表查找失败平均查找长度_Python数据结构与算法56:排序与查找:冲突解决方案...
注:本文如涉及到代码,均经过Python 3.7实际运行检验,保证其严谨性. 本文阅读时间约为6分钟. 前面说过,如果两个数据项被散列映射到同一个槽,需要一个系统化的方法在散列表中保存第二个数据项,这 ...
- 折半查找的思想及源码_结构与算法(04):排序规则与查找算法
一.递归算法 递归就是方法自己调用自己,每次调用时传入不同的变量,可以让代码变得简洁.递归算法在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法,递归式方法可以被用于解决很多的计算 ...
最新文章
- 电脑录屏工具_屏幕录制工具有哪些?这些录屏软件须知
- 【408预推免复习】计算机组成原理之计算机的运算方法
- .NET常见问题汇总
- 安装MYSQL自定义安装路径
- python笔记:深拷贝与浅拷贝
- 载winpcap4.1.1_最常用的11个电缆载流量数据表,建议收藏备用
- js与php时间戳,js时间戳与日期格式之间的互转
- Java开发全套学习!java判断字符串中是否包含中文
- Arduion 底层原理之 Uart函数 串口收发 串口协议解析
- 批量部署windows和linux系统,使用Cobbler批量部署Linux和Windows:Windows系统批量安装(三)...
- java色号_RGB颜色与16进制颜色的换算方法
- 微信小程序扫描程序码携带参数
- 马尔可夫决策过程和贝尔曼方程
- php表格制作底纹怎么做,HTML表格标记教程(36):表头的背景色属性BGCOLOR
- [Java Web]AJAX Axios | 一种结合HTML来取代传统JSP的技术
- 回车符号和换行符号原来是这样产生的
- HTML5七夕情人节表白网页(烂漫的空中散落的花瓣3D相册) HTML+CSS+JS 求婚 html生日快乐祝福代码网页 520情人节告白代码 程序员表白源码 3D旋转相册 js烟花代码
- 青海出游全年时间表,你要收藏哟!
- itunes更新系统显示网络连接到服务器,iTunes网络连接被重设怎么办
- 剑指 Offer 39. 数组中出现次数超过一半的数字
热门文章
- python遍历循环中的遍历结构可以是什么_(一)Python入门-4控制语句:06for循环结构-遍历各种可迭代对象-range对象...
- mysql怎么回复.from的数据库_mysql怎么回复.from的数据库
- html 遍历div内check,vue+element中checkbox 实现遍历分组全选
- 【转】dcmtk程序包综述(2)!!!!!
- 【转】ABP源码分析三十四:ABP.Web.Mvc
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
- php对接钉钉_php实现钉钉业务报警机器人
- 设计模式(二)设计模式的本质
- REVERSE-PRACTICE-BUUCTF-17
- oracle行转列 case,Oracle 行转列总结 Case When,Decode,PIVOT 三种方式