HeapSort 代码适用于较小的数组,但不适用于较大的数组
HeapSort code works on smaller arrays but not bigger ones
def heapSort(arr, end):
'''Heap Sort Algorithm'''
'''Average Case: O(n*log(n))'''
'''Worst Case: Θ(n*log(n))'''
'''Best Case: Ω(n*log(n))'''
if end <= 0 or len(arr) <= 1: #algorithm ends when there's one element or less
return arr
buildHeap(arr, end)
arr[0], arr[end] = arr[end], arr[0]
end -= 1
return heapSort(arr,end)
def buildHeap(arr, end):
'''Builds the Max Heap'''
if end <=0: #recursively max heap half of arr to the start
return arr
i = (end-1)//2 #parent
while i >= 0: #index backwards, swapping the parent with the bigger of each child
leftChild = 2*i+1
rightChild = 2*i+2
if arr[leftChild] > arr[rightChild] and arr[leftChild] > arr[i] and rightChild <= end: #make sure right child is within our end bounds
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif arr[rightChild] > arr[leftChild] and arr[rightChild] > arr[i] and rightChild <= end:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
i-=1
end-=1
return buildHeap(arr, end)
from random import randint
A = [randint(1,100) for i in range(20)]
print(A)
print(heapSort(A, len(A)-1))
上面是我下面的堆排序代码,错误发生在我的buildHeap函数(if行)。在所有初始运行中,右边的 child 最终等于数组的长度(而不是 array-1 的长度),因此代码超出了索引范围。奇怪的是,我的 Python 算法实现适用于较小的列表。关于如何修复 and/or 改进我的代码的任何帮助?
您在以下语句中进行 within-bounds 检查为时已晚,因为在进行检查时您已经引用了 arr[rightChild]
。你应该首先检查——作为守卫——然后才访问arr[rightChild]
。所以替换:
if arr[leftChild] > arr[rightChild] and arr[leftChild] > arr[i] and rightChild <= end: #make sure right child is within our end bounds
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif arr[rightChild] > arr[leftChild] and arr[rightChild] > arr[i] and rightChild <= end:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
与:
if arr[leftChild] > arr[i] and (rightChild > end or arr[leftChild] > arr[rightChild]):
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif rightChild <= end and arr[rightChild] > arr[i]:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
顺便说一句,您的堆构建函数效率不高。它的时间复杂度为 O(n²),使用 O(n) 额外(堆栈)space,而这可以在线性时间和常数额外 space 中完成,使用 Floyd's method。
def heapSort(arr, end):
'''Heap Sort Algorithm'''
'''Average Case: O(n*log(n))'''
'''Worst Case: Θ(n*log(n))'''
'''Best Case: Ω(n*log(n))'''
if end <= 0 or len(arr) <= 1: #algorithm ends when there's one element or less
return arr
buildHeap(arr, end)
arr[0], arr[end] = arr[end], arr[0]
end -= 1
return heapSort(arr,end)
def buildHeap(arr, end):
'''Builds the Max Heap'''
if end <=0: #recursively max heap half of arr to the start
return arr
i = (end-1)//2 #parent
while i >= 0: #index backwards, swapping the parent with the bigger of each child
leftChild = 2*i+1
rightChild = 2*i+2
if arr[leftChild] > arr[rightChild] and arr[leftChild] > arr[i] and rightChild <= end: #make sure right child is within our end bounds
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif arr[rightChild] > arr[leftChild] and arr[rightChild] > arr[i] and rightChild <= end:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
i-=1
end-=1
return buildHeap(arr, end)
from random import randint
A = [randint(1,100) for i in range(20)]
print(A)
print(heapSort(A, len(A)-1))
上面是我下面的堆排序代码,错误发生在我的buildHeap函数(if行)。在所有初始运行中,右边的 child 最终等于数组的长度(而不是 array-1 的长度),因此代码超出了索引范围。奇怪的是,我的 Python 算法实现适用于较小的列表。关于如何修复 and/or 改进我的代码的任何帮助?
您在以下语句中进行 within-bounds 检查为时已晚,因为在进行检查时您已经引用了 arr[rightChild]
。你应该首先检查——作为守卫——然后才访问arr[rightChild]
。所以替换:
if arr[leftChild] > arr[rightChild] and arr[leftChild] > arr[i] and rightChild <= end: #make sure right child is within our end bounds
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif arr[rightChild] > arr[leftChild] and arr[rightChild] > arr[i] and rightChild <= end:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
与:
if arr[leftChild] > arr[i] and (rightChild > end or arr[leftChild] > arr[rightChild]):
arr[i], arr[leftChild] = arr[leftChild], arr[i]
elif rightChild <= end and arr[rightChild] > arr[i]:
arr[i], arr[rightChild] = arr[rightChild], arr[i]
顺便说一句,您的堆构建函数效率不高。它的时间复杂度为 O(n²),使用 O(n) 额外(堆栈)space,而这可以在线性时间和常数额外 space 中完成,使用 Floyd's method。