python找重复元素及对应角标_用Python实现十大经典排序算法-插入、选择、快速、冒泡、归并、希尔、插入、桶、基数、计数...

2328b1bcac4dd9f3b907b1457471f15d.png

本文来用图文的方式详细讲解了Python十大经典排序算法 —— 插入排序、选择排序、快速排序、冒泡排序、归并排序、希尔排序、插入排序、桶排序、基数排序、计数排序算法,想要学习的你们,继续阅读下去吧,如果觉得不错的话,推荐给身边的朋友吧。

b88adebdae72d3c87238ef278cc0d8ad.png

插入排序

思路本文用图文的方式详细讲解了Python经典排序算法,想要学习的你们,继续阅读下去吧,如果觉得不错的话,推荐给身边的朋友吧。

b88adebdae72d3c87238ef278cc0d8ad.png

插入排序

思路

  1. 从第一个元素开始,该元素可以认为已经被排序;
  2. 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  3. 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  5. 将新元素插入到该位置;
  6. 重复步骤2~5。

代码

d897e93ffd3a744367462c72bad1c2d2.png

图示

0a6b6120d9764dd6158a56dbedf8ccaa.png

平均时间复杂度

O(n^2)

希尔排序

前言

希尔排序是插排的升级,先将待排序的元素进行分组,在分组的基础上进行插排,从而降低整体上的时间复杂度。

这里面设计到一个增量的概念,我们依据增量来决定分组的跨度。常用的增量有三种:

  • 希尔增量 [1,2,4,8,…,2^(k-1)]
  • 海巴德增量 [1,3,7,15,…,2^k-1]
  • 塞基维克增量 [1,5,19,41,…,4k-3*2k+1]

一般情况下希尔增量带来的时间复杂度小于O(n2),但在极坏情况下可能效果不明显甚至超过这个值。海巴德增量可以将时间复杂控制在O(n(3/2))以下,而塞基维克增量该项参数为O(n^(4/3))。

思路

  1. 择定增量
  2. 分组
  3. 组内比较
  4. 重复步骤2,3直到跨度为1

图示

47633965086599cc22186dae7bb9c696.png

代码

6e07ed8a41c1315c769935255df5fc4c.png

选择排序

思路

  1. 选出数组中最大(最小)的元素放到开头
  2. 在剩下的元素中选中最大(最小)元素放到上个被选元素之后
  3. 重复2步骤

图示

81cda530e67a88716a6b868b47a395f4.png

代码

b4ebbb7e2858f69b62d06fc083b5c077.png

平均时间复杂度

O(n^2)

堆排序

前言

堆排序,顾名思义,就是基于堆。因此先来介绍一下堆的概念。

堆分为最大堆和最小堆,其实就是完全二叉树。最大堆要求节点的元素都要大于其孩子,最小堆要求节点元素都小于其左右孩子,两者对左右孩子的大小关系不做任何要求,其实很好理解。有了上面的定义,我们可以得知,处于最大堆的根节点的元素一定是这个堆中的最大值。其实我们的堆排序算法就是抓住了堆的这一特点,每次都取堆顶的元素,将其放在序列最后面,然后将剩余的元素重新调整为最大堆,依次类推,最终得到排序的序列。

思路

  1. 把堆顶的最大数取出
  2. 将剩余的堆继续调整为最大堆
  3. 重复步骤1,2

图示

855505a956a7bf75747763904eb0ce50.png

代码

627f5842d28a9926a91678ce9f283e60.png

3f965637ff8b61d2e44768a04f14c351.png

平均时间复杂度

O(nlogn)

冒泡排序

思路

  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

图示

e353118d802a09cf9f5eb1f35608f94d.png

代码

1ca293bc67d7cda840b86b723396cfd1.png

平均时间复杂度

O(n^2)

快速排序

思路

  1. 先从集合中取出一个数作为“哨兵”
  2. 将集合中比哨兵大的元素和比哨兵小的元素分列两侧
  3. 再对左右区间重复第二步,直到各区间只有一个数

图示

8e6a310855f1e3abfed9f977a7c554c1.png

代码

df2bb22886bc6c1c63ce244d3fa65f57.png

平均时间复杂度

O(nlogn)

归并排序

思路

  1. 将列表拆分成两个有序子模块
  2. 递归拆分
  3. 子模块内部进行排序并合并成大的模块
  4. 递归合并

图示

bba13ef01ef3fb1540c81c4ade7d96dc.png

代码

be58ac9d3a875c3e28e84f8bdc6cca3c.png

平均时间复杂度

O(nlogn)

计数排序

思路

  1. 找出集合中最小数m和最大数n
  2. 建一个长为(m-n+1)的列表count_list,所有元素初始化为0
  3. 遍历集合,元素减去n得到的结果作为index,将count_list该位上的元素加1。
  4. 初始化空列表result。
  5. 将count_list序列化,用索引值减去n,得到的结果追加到result中,索引值对应的位元素值减1,直到它为0。
  6. 重复步骤5。

图示

926d38eeab446c63c135a73152d1a207.gif

代码

e8a1e1ae33dc86fd64742858c0f796ed.png

平均时间复杂度

O(n)

桶排序

前言

桶排序是将待排序集合中处于同一个值域的元素存入同一个桶中,也就是根据元素值特性将集合拆分为多个区域,则拆分后形成的多个桶,从值域上看是处于有序状态的。对每个桶中元素进行排序,则所有桶中元素构成的集合是已排序的。

思路

  1. 根据待排序集合中最大元素和最小元素的差值范围和映射规则,确定申请的桶个数;
  2. 遍历待排序集合,将每一个元素移动到对应的桶中;
  3. 对每一个桶中元素进行排序,并移动到已排序集合中。

图示

f8a6002f4d7439a86dbaafab7b0e487f.png

代码

bca69d14bb76b8de727b765761927f30.png

平均时间复杂度

O(n^2)

基数排序

思路

  1. 首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶中;
  2. 接下来将这些桶中的数值重新串接起来,成为以下的数列。接着再进行一次分配,这次是根据十位数来分配;
  3. 接下来将这些桶中的数值重新串接起来,持续进行以上的动作直至最高位数为止。

图示

e4750fe3c2715b96d4dead053da62be0.png

代码

444c04f757b77c8e70f697175586c6c9.png

平均时间复杂度

O(d*2*n), 这里的d是数值位数

本文来自热心好友原味吐司的投稿,点赞!

更多有关python、深度学习和计算机编程的精彩内容,可以关注微信公众号:码农的后花园

d5d2ecf4a9b9a1c2ed32b69ffa9f74d2.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值