算法基础第二章O(N*logN)的排序

归并排序

先排序左边,再排序右边,最后通过一个辅助数组merge
利用master公式估计时间复杂度:

T(N) = 2*T(N/2) + O(N)
a = 2, b=2, d=1

时间复杂度为:O(N*logN),额外空间复杂度:O(N)

拓展:

  1. 小和问题
    数组中求每个数左边比他小的数的和。
    普通解法:O(N^2)
    归并解法:在merge和sort的过程中发现左侧数比右侧数小就把 “小和” 加上

  2. 逆序对问题
    左边的数比右边的数小

堆(优先级队列)

数组实现的完全二叉树(从左到右依次变满)结构

节点个数是N, 高度是logN.

i 位置的左孩子是2i+1, 右孩子是2i+2, 父节点是 (i-1)/2

根节点为0
  1. 方法
  2. add (member)
    新加入的数据放到最后位置,并依次和父节点比较大小, 若比父节点大则交换两者位置.
  3. intgetmax()
    输出最大值,并更新最大堆
    返回最大值后, 把最后一个数放到根节点, 然后和最大子节点比较大小并调整. heapify()
  4. 扩容
    一次扩大一倍

堆排序

  1. 先满足0~0范围是堆,然后依次添加数字,逐渐建立堆O(N*logN)

    如果一次性得到全部数据, 从下往上逐渐保证每个子树调整成大根堆的时间复杂度更低 O(N).
    
  2. 每次把根节点和最后一个节点交换, 并将heapsize减1

  3. 将新的根节点向下heapify到目标位置

  4. 重复2,3过程,直到heapsize等于0

时间复杂度: O(N*logN)

例题:
一个几乎有序的数组, (每个元素移动距离不超过k, k比较小) 选择最佳排序方法.

利用一个大小为k的最小堆, 每次弹出最小的放到0位置(1,2,3…), 再把后一个(k+1)数放进堆里, 周而复始.
O(N*logk) -> O(N)

python中的堆

默认为小根堆, 若需要大根堆, 保存成相反数 (加负号)

import heapq
heap = []#建立一个常见的堆

heappush(heap,item)#往堆中插入一条新的值

item = heappop(heap)#弹出最小的值

item = heap[0]#查看堆中最小的值,不弹出

heapify(x)#以线性时间将一个列表转为堆

item = heapreplace(heap,item)#弹出一个最小的值,然后将item插入到堆当中。堆的整体的结构不会发生改变。
heappoppush()#弹出最小的值,并且将新的值插入其中

merge()#将多个堆进行合并

nlargest(n , iterbale, key=None)从堆中找出做大的N个数,key的作用和sorted( )方法里面的key类似,用列表元素的某个属性和函数作为关键字

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值