快排序算法(上)

简介: 快排序算法(上)

承接上文归并排序及小和问题

归并排序扩展-逆序对问题

在一个数组中,左边的数如果比右边的数大,则两个数构成一个逆序对,找到逆序对的数量

比如 3,2,4,5,0

所有的逆序对是 3,2;  3,0;  2,0;  4,0;  5,0

上文的小和问题是 求右边有多少个数比左边的数大

这个题目是求右边有多少个数比左边的数小

所以逆序对的问题和小和问题是等效的

归并排序为什么不会重算和漏算或归并排序的实质

一个数组[a,b,c,d,e,f,g,h,i]

就看数字c 看它经历什么样的心路历程

一开始数组是这么被分的

image.png

当a和b整体产生小和变成有序之后 跟c合并的过程

c不产生小和

因为右组所有的数都不会产生小和

然后a,b,c就变成了一个有序的部分

c在哪里不重要

接下来 a,b,c这个整体和d,e所在的组合并

这样合并的时候c产生的小和数量它的范围被扩到右侧的d,e范围上

d,e这个范围上有可能有比c大的(有0个比c大的,有1个比c大的,有2个比c大的)

具体哪种情况不重要,重要的是c已经把自己求有多少个数比自己大的范围扩到d,e上

然后a,b,c,d,e共同构成一个有序的部分,c在哪里不重要

重要的是下面会和f,g,h,i所在的数组

去求这个范围上有多少个数比c大

c先去求de范围有多少个数比c大

再去求f,g,h,i范围有多少个数比c大

a,b,c,d,e,f,g,h,i 这些数成为一个整体

c在哪个位置不重要

如果右侧还有一个范围 则c所在的这个整体会继续求那个右侧的范围有多少个数比c大

c在求有多少个数比它大的范围是右侧依次往外扩的

所以说它不会漏算

为什么说不会重算?

因为c一旦跟某一个右组合并了之后

它们就会变成一个组

而一个组内部是不会产生小和的

只有左组和右组之间才会产生小和

c只是一个普通的一员而已 对于所有的数来说都是这个过程

所以求每一个数的小和都不会漏算 都不会重算

荷兰国旗问题

怎么把一组数做划分 左边都小于它 右边都大于它 中间都等于它

1、问题1

左边都小于等于number,右边都大于number

不要求有序 只要求对数组进行划分

image.png

比如 一个数组是 3,5,6,7,4,3,5,8

number是5

所有小于等于5的放左边,大于5的放右边

准备一个变量表示小于等于区域的右边界

一开始在数组的最左侧

image.png

当前来到的位置是i位置

当来到i位置就会有两种情况

第一种是小于等于number的

第二种是大于number

1)i所在当前位置的数<=number

把当前数[i]和<=区的下一个数做交换

然后<=区往右扩一个位置

当前数也跳下一个i++

如图第一个数是3

3<5

3和<=区的下一个数也是3 即自己和自己交换

交换完之后 <=区往后扩

当前数跳下一个


image.png

当前数是5 也满足 <=number

5和5 自己和自己交换 <=区向右扩

当前数下移


image.png

此时当前数6大于5 命中第二种情况

i直接跳下一个

image.png

当前数是4 ,<=number的

把它跟<=区的下个数做交换

4和6做交换

<=区往右扩

当前数也跳下一个

image.png

有中了情况1

把当前数和下个数做交换

<=区往右扩

当前数跳下一个

image.png

当前数是8 ,i++ 越界了

此时已经做到了 <=区都是<=5的 ,右侧都是>5的

image.png

i是当前来到的位置

右侧是还未看过的位置 待定区域

<=区域里面都是<=已经做到的位置

<=区域和i中间的位置大于区域

荷兰国旗问题🇳🇱

小于区域放左边 中间都是等于number的 右边都是大于number的

image.png

小于和大于区域都不要求有序

当然可以没有小于区域或等于区域或大于区域 如果有的话 严格分开

时间复杂度是O(N) 用有限几个变量

定义两个变量 一个是小于区域的左边界

一个是大于区域的右边界

image.png

相关文章
|
3月前
|
搜索推荐 索引
排序算法详解
本文介绍了多种排序算法,包括插入排序(如直接插入排序和希尔排序)、选择排序(如直接选择排序和堆排序)、交换排序(如冒泡排序和快速排序)以及归并排序和计数排序。插入排序通过构建有序序列逐步插入元素;选择排序通过不断选择最小元素放置于序列起始;交换排序通过元素间的交换达到排序目的;归并排序采用分治法将序列分解再合并;计数排序则通过统计元素出现次数来排序。文章详细阐述了各种排序算法的原理及其实现方法。
40 6
排序算法详解
|
7月前
|
搜索推荐 算法 数据处理
C++中的排序算法
C++中的排序算法
50 0
|
7月前
|
搜索推荐 算法 Shell
排序算法(C/C++)
排序算法(C/C++)
排序算法(C/C++)
|
搜索推荐 C++
89 C++ - 常用排序算法
89 C++ - 常用排序算法
40 0
|
算法 搜索推荐 Java
TimSort——最快的排序算法
TimSort 算法是 Tim Peters 于 2001 年为 Python 语言创建的。该算法建立在插入排序和归并排序的基础之上,兼具插入排序和归并排序的优点。TimSort 的平均时间复杂度为 O(nlog(n)) ,最好情况 O(n) ,最差情况 O(nlog(n)) 。空间复杂度 O(n) ,是一个稳定的排序算法。
1582 0
TimSort——最快的排序算法
|
算法 搜索推荐 Java
常见排序算法详解(1)
前言 排序是我们在日常生活和工作中常见的一种操作。在计算机科学中,排序算法就是将一串或一组数据按照特定的顺序进行排列的算法。这些顺序可能是数字的升序或降序,也可能是字母或字词的字母顺序等。我们将探讨几种不同的排序算法,包括他们的原理、优缺点以及代码实现。
130 0
|
机器学习/深度学习 存储 缓存
第 7 章 排序算法
第 7 章 排序算法
93 0
|
算法 搜索推荐 C++
|
搜索推荐 算法
常见的排序算法(下)
上期学习完了前四个排序,这期我们来学习剩下的三个排序:
常见的排序算法(下)
|
移动开发 人工智能 搜索推荐
排序算法总结
总结了常用的排序算法