python - 计算堆排序中比较和排列的次数
问题描述
我正在尝试计算堆排序算法中的比较和交换次数(相应的 num_comps 和 num_swaps ):
import numpy as np
import timeit
def heapify(arr, len_arr, i):
num_swaps = 0
num_comps = 0
maxima = i
l = 2 * i + 1
r = 2 * i + 2
num_comps += 1
if l < len_arr and arr[i] < arr[l]:
maxima = l
num_comps += 1
if r < len_arr and arr[maxima] < arr[r]:
maxima = r
if maxima != i:
num_swaps += 1
arr[i], arr[maxima] = arr[maxima], arr[i]
heapify(arr, len_arr, maxima)
return num_swaps, num_comps
def heap_sort(arr):
num_swaps = 0
num_comps = 0
len_arr = len(arr)
for i in range(len_arr, -1, -1):
heapify(arr, len_arr, i)
for i in range(len_arr - 1, 0, -1):
num_swaps += 1
arr[i], arr[0] = arr[0], arr[i]
heapify(arr, i, 0)
return num_swaps, num_comps
flag = input("If you wanna randomize entered data, press 'Enter'. To enter manually press any other key: ")
if flag == '':
arr = np.random.randint(-10000, 10000, 1000)
else:
while True:
try:
arr = []
for i in range(10):
a = int(input(f'Enter {i + 1} element: '))
arr.append(a)
break
except ValueError:
print("Input an integer!")
print(f'Non-sorted array: \n {arr}')
num_comps, num_swaps = heap_sort(arr)
len_arr = len(arr)
print(f'Sorted array: \n {arr}')
print(num_comps, 'comparisons were executed')
print(num_swaps, 'swaps were executed ')
t = timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)
print(f"Program was executed by {t} seconds")
我的代码有效,但显示错误的值。我知道我做错了什么,但我不明白到底是什么。我只是在学习 python 函数,所以请给我看代码示例。如果有任何帮助,我将不胜感激。
UPD:我根据@Luke19 的回答修改了我的代码,但我仍然有错误的值(要排序的 1000 个数字、1000 个比较和 2 个交换)。
解决方案
您的heapify
函数返回两个对象,因此您应该使用与heap_sort
*:相同的语法num_swaps, num_comps = heapify(...)
。如果你不这样做,你的num_comps
变量将不会在heap_sort
.
更新:
请注意,使用全局变量通常并不理想。(例如,您可以在此处和此处找到有关该问题的一些讨论。)通常,如果有一种简单的解决方法,您应该避免使用它们,以减少容易出错的代码。
因此,我将为您提供有关如何在不使用全局变量的情况下修复代码的更详细说明:
首先,请注意num_swaps
并且num_comps
每次调用时都需要更新heapify
,即使在heapify
内部调用时也是如此!但是,在您的原始代码中,这两个计数器每次heapify
被调用时都被重置为零。因此,为了让它们保持当前值,您需要做的就是将它们作为参数包含到 中heapify
,然后使用返回的值来更新原始值。
这是使用您自己的代码的示例:
#notice the change to the function's arguments
def heapify(arr, len_arr, i, num_swaps, num_comps):
maxima = i
#etc...
#then every time you call heapify, pass your current num_swaps and
# num_comps then update them by setting them to the returned values:
if maxima != i:
num_swaps += 1
arr[i], arr[maxima] = arr[maxima], arr[i]
num_swaps, num_comps = heapify(arr, len_arr, maxima, num_swaps, num_comps) #notice the change to the line
return num_swaps, num_comps
因为您传递的是andheapify
的当前本地值,所以每次您都将更新这些变量的本地值。num_swaps
num_comps
num_swaps, num_comps = heapify(...,num_swaps, num_comps)
heapify
您应该对函数内部的调用执行相同的操作heap_sort
:
def heap_sort(arr):
num_swaps = 0
num_comps = 0
len_arr = len(arr)
for i in range(len_arr, -1, -1):
num_swaps, num_comps = heapify(arr, len_arr, i, num_swaps, num_comps) #notice the change to this line
#etc....
return num_swaps, num_comps
希望这可以帮助!让我知道是否清楚。
推荐阅读
- python - Pandas:通过在行级别应用自定义函数来创建列
- javascript - 填充 Google Charts API,得到“列标题行必须是一个数组”。
- react-testing-library - 如何使用反应测试库修复错误“在 jest.settimeout() 指定的 5000 毫秒内未调用异步回调?
- python - 通过在没有循环的情况下转换其 RGB 将 RGB 值更改为单个值
- regex - 更新 IIS 中的 URL 查询字符串 IIS 中的 URL 重写
- databricks - 仅在计划作业运行时无法推断 Parquet 的架构
- google-chrome-extension - 当 storage.sync 超出配额时如何同步 Chrome 扩展 Storage.local
- javascript - Discord.js-commando 节流不起作用
- png - sws_scale PAL8 到 RGBA 返回不清晰的图像
- node.js - 将图像上传到 SailsJS(通过 Skipper)并在流中调整大小