堆数据结构是二叉树的数据结构。
堆排序主要为建堆,然后就是依次取出最大或者最小值,取出后并调整堆。
与插入排序相同,堆排序具有空间原址性。
如果从小到大排序,建立的是最大堆,把最大的元素(堆顶元素)取出,与数组末端数据进行替换,依次取出,直到所有数据都排好序。
堆排序的时间复杂度是o(n*logn)。
下面是堆排序的python实现,其中数组下标从0开始,因此父亲、左孩子、右孩子节点的坐标的计算方式有所不同,可以自己推导下。
#coding:utf-8
# 父节点坐标
def parent(i):
return (i-1)>>1
# 左孩子节点坐标
def left(i):
return 2*i + 1 # 如果用位运算的话,注意是 (i<<1) + 1 而不是 i<<1+1 (相当于4*i) , 因为位运算优先级小于加减运算优先级
# 右孩子节点坐标
def right(i):
return 2*i + 2
# 调整为最大堆
def max_heapify(arr,heap_size,i):
l = left(i)
r = right(i)
largest = i
if l<heap_size and arr[l]>arr[i]:
largest = l
if r<heap_size and arr[r]>arr[largest]:
largest = r
if largest != i:
# 交换 arr[i] 和 arr[largest] 注:可以直接使用 arr[i],arr[largest] = arr[largest],arr[i]
arr[i] = arr[i]^arr[largest]
arr[largest] = arr[i]^arr[largest]
arr[i] = arr[i]^arr[largest]
max_heapify(arr,heap_size,largest)
def build_max_heap(arr):
heap_size = len(arr)
for i in range(parent(heap_size-1), -1, -1):
max_heapify(arr, heap_size, i)
def heap_sort(arr):
# 构建最大堆
build_max_heap(arr)
# 堆排序
for i in range(len(arr)-1, 0, -1):
# 交换 arr[0] arr[i] 注:可以直接使用 arr[i],arr[0] = arr[0],arr[i]
arr[0] = arr[0]^arr[i]
arr[i] = arr[0]^arr[i]
arr[0] = arr[0]^arr[i]
max_heapify(arr,i,0)
def show_arr(arr):
print "[", ", ".join([str(x) for x in arr]), "]"
if __name__ == "__main__":
arr = [4,1,3,2,16,9,10,14,8,7]
heap_sort(arr)
show_arr(arr)