python数据结构——快速掌握简单高效的堆排序heapq库堆算法

目录

堆的定义

堆满足以下特性:

堆的存储

heapq模块

创建堆:

heapq.heapify(li)

heapq.heappush(li, num)

heapq.heappop(li)

heapq.heappushpop(li, num)

heapq.heapreplace(li, num)

heapq.merge(li,li2)

heapq.nlargest(n, li, key=None)

heapq.nsmallest(n, li, key=None)

堆排序:


python堆与堆排序——heapq库

        堆排序与快速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先讲解下什么是数据结构中的堆。

堆的定义

堆是完全二叉树或者是近似完全二叉树。

堆满足以下特性:

父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。

每个结点的左子树和右子树都是一个堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于任何一个子节点的键值时为最大堆。当父结点的键值总是小于或等于任何一个子节点的键值时为最小堆。而heapq模块就是以最小堆写的:

堆的存储

        一般都用列表来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。

heapq模块

引用库的方法:import heapq;如果想省去前缀就使用from heapq import*

创建堆:

创建一个堆,可以使用list来初始化为 [] ;也可以通过一个函数 heapify(),来把一个list转换成堆

heapq.heapify(li)

将自身list 转换成堆,在线性时间内。

from heapq import*

li=[5,2,0,1,3,1,4]
heapify(li)
print(li)

输出:

[0, 1, 1, 2, 3, 5, 4]

heapq.heappush(li, num)

num 的值加入 li 中,并保持堆不变

heappush(li,8)

print(li)

输出:

[0, 1, 1, 2, 3, 5, 4, 8]

heapq.heappop(li)

弹出并返回 li 的最小的元素,保持堆的不变性。如果堆为空,抛出 indexError。

使用 heap[0] ,可以只访问最小的元素而不弹出它。

heappush(li,8)
print("pop前是{}".format(li[0]))
heappop(li)
print("pop后是{}".format(li[0]))
print(li)

输出:

输出前是0
pop后是1

[ 1, 1, 2, 3, 5, 4, 8]

heapq.heappushpop(li, num)

num 放入堆中,然后弹出并返回 li 的最小元素。该组合操作比先调用 heappush()再调用 heappop()运行起来更有效率。

heappushpop(li,3)
print(li)

输出:

[1, 2, 4, 3, 3, 5, 8]

heapq.heapreplace(li, num)

弹出并返回 li 中最小的一项,同时推入新的 num。 堆的大小不变。 如果堆为空则引发 indexError。

这个单步骤操作比 heappop()加 heappush() 更高效,并且在使用固定大小的堆时更为适宜。 pop/push 组合总是会从堆中返回一个元素并将其替换为 num

返回的值可能会比添加的 num 更大。 如果不希望如此,可考虑改用 heappushpop()。 它的 push/pop 组合会返回两个值中较小的一个,将较大的值留在堆中。

heapreplace(li,7)
print(li)

输出:

[2, 3, 4, 3, 7, 5, 8]

heapq.merge(li,li2)

将多个堆合并

from heapq import*
li=[1, 1, 4, 2, 3, 5, 8]
li1=[2,1,2,3,2,4,6]
heapify(li)
heapify(li1)
lists=merge(li,li1)
print(list(lists))

输出:

[1, 1, 2, 1, 2, 3, 2, 4, 2, 3, 4, 5, 6, 8]

heapq.nlargest(n, likey=None)

li 所定义的数据集中返回前 n 个最大元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 li 的每个元素中提取比较键 (例如 key=str.lower)。

from heapq import*
li1=["Jsfas","sdaks","Ksfaz","gdssd"]
heapify(li1)
print(li1)#原堆
list1=nlargest(2,li1,key=str.lower)#有key的输出
list2=nlargest(2,li1)#没key的输出
print(list1)
print(list2)

输出:

['Jsfas', 'gdssd', 'Ksfaz', 'sdaks']
['sdaks', 'Ksfaz']
['sdaks', 'gdssd']

heapq.nsmallest(n, likey=None)

li 所定义的数据集中返回前 n 个最小元素组成的列表。 如果提供了 key 则其应指定一个单参数的函数,用于从 li 的每个元素中提取比较键 (例如 key=str.lower)

同上原理

堆排序:

def heapsort(li):
    h = []
    for value in li:
        heappush(h, value)
    return [heappop(h) for i in range(len(h))]

print(heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0]))

输出:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

你可能感兴趣的:(Python,蓝桥杯算法,数据结构,排序算法,算法,python)