利用二叉树进行排序_堆排序_python实现

堆排序

个人总结
1)你需要确定你要使用堆排序得到顺序数组(小到大),还是逆序数组(大到小):

若是顺序数组:你需要编写一个函数得到大顶堆,也就是,把二叉树中最大的元素调换到根节点位置。

若是逆序数组:则相反,将二叉树调整为小顶堆,即最小元素在根节点。

2)堆排序最复杂的部分就是如何将二叉树调整为大顶堆和小顶堆。使用3,1,2这三个数来解释一下,假设3为二叉树的根节点,1为左子树,2为右子树。调整步骤为:

  • 先比较左子树和右子树的大小,记录较大元素的下标。
  • 再比较子树较大元素和根节点元素,若根节点小于它,则交换两者位置。

:其次是如何处理更为复杂的二叉树,其实就是循环的找出所有非叶子节点。这里有个公式可以计算非叶子节点的下标,index=2*i+1。

3)最后就是再找出最大值和最小值后,与二叉树的最后一个位置进行交换,然后再它的基础上重复进行寻找最大值和最小值的操作,并进行交换。

import time
import random

arr = [0 for i in range(800000)]
for i in range(800000):
    arr[i]=random.randint(0,800000)

def heapSort(arr):
    print("堆排序")
    i = int(len(arr)/2)-1
    while i>=0:
        adjustHeap(arr,i,len(arr))
        i-=1
    #print(arr)
    
     #处理大顶堆的子树
    j=len(arr)-1
    while j>0:
        #交换
        temp=arr[j]
        arr[j]=arr[0]
        arr[0]=temp
        adjustHeap(arr,0,j)
        j-=1
    print(arr)
    
#功能:将非叶子节点调整为大顶堆
#arr为数组,i为父节点索引,length为长度
def adjustHeap(arr,i,length):
    temp = arr[i]#存储父节点
    k=i*2+1
    while k<length:
        #说明左子节点小于右子节点
        if k+1<length and arr[k]<arr[k+1]:
            k+=1
        #如果子节点大于父节点
        if arr[k]>temp:
            arr[i]=arr[k]#将父节点换成三个数中最大的那个
            i=k#i指向子节点中刚刚交换的那个位置
        else:
            break
        k=k*2+1
        
    arr[i]=temp#把父节点的值放进子节点

print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))       
heapSort(arr)
print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))



你可能感兴趣的:(利用二叉树进行排序_堆排序_python实现)