| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 什么?一篇理解排序算法(下) -> 正文阅读 |
|
[数据结构与算法]什么?一篇理解排序算法(下) |
目录 一、快速排序1、partition操作分析0)首先如果区间内只有一个元素 那我们默认是有序的 1)从区间内(区间不代表整个数组,而是指[from,to]的数组片段)挑选一个privot,挑选方式随意 2) 遍历区间,每个元素都要和privot比较,小于等于privot的放左边,大于等于privot的放右边,区间遍历完成后数组被分为三部分 整个过程我们称之为parttion 3)递归地对左右区间进行parttion ques:为什么这样的操作就可以使得数组有序? ans:我们每次parttion都会确定privot的最终位置,相当于排序了一个元素,递归的处理就可以让每个元素都放在自己该放的位置,进而使得数组有序 ques:partition==快排? ans:parttion不是快排,他只是快排中的一个步骤 2、partition之Hoare划分:老规矩先上图: hoare划分又被叫做左右指针法: 1)首先选一个基准值temp(一般来说不是最左就是左右)这里我们取左 2)定义指针left和right,left从左往右,找到比temp大的元素停下,right从右往左,找到比temp小的元素停下 此时left和right交换,继续寻找 3)直到left和right相遇,此时temp和left或者right交换即可 这里有一个小技巧,如果选取 左边为temp,就要right先动,如果选取右边为temp,就要left先动 为什么? 首先举一个反例: 数组【0,1,2,3,4】 我们选取0为temp,然后left从左往右,直到下标为3时和right相遇,此时交换0和4,数组排序错误 其次是我个人的理解: 在我们最后交换相遇点和最左边的值时,temp被交换到左边,为什么我们可以保证这个点一定小于temp呢? 正是因为right先动! right停下来只有两种可能: 1)temp找到了一个小于temp的元素所以停下来 2)temp遇到了left,而left由于后动,所以left上的值是严格小于等于temp的 为什么left一定严格小于等于temp? 两种可能: 1)left没动过,那么left就是temp 2)left动过,而由于left和right交换过,所以left当前的值一定小于temp 代码如下:
3、parttion之挖坑法上图: 1)还是选择基准值,我们依旧选择左边,用变量temp保存基准值,并在原temp位置留下一个坑 2) 定义指针left和right,right先动,找到一个比temp小的元素,把这个元素入坑,然后在right的位置上留下一个坑,此时left开始动,找到一个大于temp的元素入坑,left开始作为坑 动right 3)如此循环往复,直到left和right相遇,把temp入坑 挖坑法代码实现:
4、parttition之前后指针法我们首先定义一个指针s和指针i 做如下定义: [start,s)? ? ?<=temp [s,i)? ? ? ? ? ? >=temp [i,end)? ? ? ? 还没有比较过的元素 我们首先选取最后一个元素为temp,然后指针i不断向后移动,如果当前元素小于temp,交换nums【s】和nums【i】,s++(因为s之前的元素必须都是小于temp的)? 如果大于 等于s不动,i还是继续++,直到i等于end 交换s和temp,由于s之前严格小于temp,所以我们经过一次parttion能够确定temp的最终位置 代码实现:
5、快速排序代码实现及其优化:有了parttion操作,快速排序就很简单了,只需要递归的使用怕parttiion方法,确定每一个小区间即可
但是我们思考:如果一开始地选取privot的操作选的是最小或者最大值,那么我们每次费尽千辛万苦只能确定privot的一侧,这就会造成递归树倾斜,使得时间复杂度为O(N^2) 因此我们对已有的快排进行优化: 1)在待排序元素较少的情况下,插排的效率是很高的,因此我们可以在元素数量到达某一个临界点时就采用插入排序 2)parttion算法优化:1、找到==privot的值,下次分割时跳过这些相等的数 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2、三指针,分别记录数组中? 左 ,中,右,三个下标,找到数值大小中间的元素,作为基准值 ,我们就可以有效避免待排序数组有序或者逆序这种最差情况 选取priovt的操作很多人都采用了随机生成数字的方式,但由于生成随机数的代价本身就很高,我们采用三数取中更为便捷!
6、快速排序时间性能分析? 空间复杂度关乎递归树的高度 最好是logn? 最差是 n 二、归并排序归并排序的本质也是一种分治算法 把一个大区间分为两个小区间,如果让两个小区间分别有序,那我们就可以通过合并数组的方式使之全部有序 ?合并两个数组: ? 完整代码:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 11:37:22- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |