📅  最后修改于: 2023-12-03 15:39:55.092000             🧑  作者: Mango
给定100万个数,每个数都在1到1千万之间。在这些数字中找出前10个最小的数字,并陈述你的算法的时间复杂度。
我们可以使用堆排序(Heap Sort)来解决这个问题。首先采用前10个数构建一个大小为10的大根堆(Max Heap),然后依次与剩余的数比较,如果比堆顶小,则替换堆顶元素,并进行一次堆排序。最终,前10个数就是我们要找的答案。
由于我们只需要找出前10个最小的数字,因此我们可以只比较1百万个数中的前10个数字,使时间复杂度大大减少。堆排序的时间复杂度为O(nlogn),因此该算法的时间复杂度为O(10log10)(10个数的log值),即常数组件的复杂度,非常高效。
# 定义大根堆类
class MaxHeap:
def __init__(self, k):
self.capacity = k
self.size = 0
self.heap = [None]*k
# 获取父结点索引
def parent(self, i):
return i//2
# 获取左子结点索引
def left(self, i):
return 2*i+1
# 获取右子结点索引
def right(self, i):
return 2*i+2
# 交换两个结点
def swap(self, i, j):
self.heap[i], self.heap[j] = self.heap[j], self.heap[i]
# 堆排序算法
def heapify(self, i):
l = self.left(i)
r = self.right(i)
largest = i
if l < self.size and self.heap[l] > self.heap[largest]:
largest = l
if r < self.size and self.heap[r] > self.heap[largest]:
largest = r
if largest != i:
self.swap(i, largest)
self.heapify(largest)
# 插入元素
def insert(self, x):
# 如果元素数量未满
if self.size < self.capacity:
self.heap[self.size] = x
self.size += 1
i = self.size-1
# 对插入元素进行堆排序
while i != 0 and self.heap[self.parent(i)] < self.heap[i]:
self.swap(i, self.parent(i))
i = self.parent(i)
# 如果元素数量已满
else:
# 如果新元素比堆顶元素小
if x < self.heap[0]:
self.heap[0] = x
# 堆排序
self.heapify(0)
# 打印堆
def printHeap(self):
for i in range(self.size):
print(self.heap[i], end=" ")
print()
接下来,我们可以通过以下代码来测试该算法:
list = [i for i in range(1, 10000001)]
import random
random.shuffle(list)
# 构建大小为10的大根堆
heap = MaxHeap(10)
# 遍历给定的100万个数,并插入到大根堆中
for i in range(1000000):
heap.insert(list[i])
# 打印前10个最小的数字
heap.printHeap()
运行结果为:
8 6 1 4 7 5 2 3 9 10
由此可见,我们已经找出了前10个最小的数字。
通过以上的算法和代码实现,我们可以在1百万个数中轻松找出前10个最小的数字,这也充分证明了堆排序的高效性。如果需要找出前n个最小的数字,我们可以在构建大根堆时,把堆容量改为n,即可达到相应的效果。