堆排序

堆排序是面試中比較常考的排序方法,所以在找工作時我們自己必須能手撕出來堆排序。

堆排序的思想爲:我們在堆排序的時候需要將數組想象成一顆完全二叉樹。那麼就滿足:每一個父節點所對應的子節點的左子樹2*n+1,右子樹爲2*n+2。將此樹變成大頂堆,然後每次取堆頂元素和堆尾的最後一個元素進行交換,然後繼續將len(list)-1進行變成大頂堆。以此類推直到遍歷所有數組。

大頂堆:任何一個樹的子樹最大值就是他的頭

小頂堆:任何一個樹的子樹最小值就是他的頭

左子樹:2*n+1

右子樹:2*n+2

代碼實現:

#完全二叉樹
#大根堆  任何一個樹的子樹最大值就是他的頭
#小根堆  任何一個樹的子樹最小值是他的頭b
#左孩子 2*i+1
#右孩子 2*i+2
class HeapSort():
    def heapSort(self,list):
        if list is None or len(list)<2:
            return

        for i in range(len(list)):
            #建立大根堆
            self.heapInsert(list,i)    #0-i

        size = len(list)-1
        list[0],list[size] = list[size],list[0]
        while size>0:
            self.heapify(list,0,size)
            size -= 1
            #再次進行最大元素與堆尾元素進行交換
            list[0],list[size] = list[size],list[0]

    def heapInsert(self,list,index):
        #如果後面的元素的值大於父節點就交換
        #可以循環到最頂端
        while list[index] > list[(index-1)//2]:
            list[index],list[(index-1)//2] = list[(index-1)//2],list[index]
            index = (index-1)//2

    #交換後讓堆變成大頂堆
    def heapify(self,list,index,size):
        left = index*2+1
        while left < size:
            #先對兩個子樹進行比較
            if left+1 < size and list[left+1] > list[left]:
                largest = left+1
            else:
                largest = left
            largest = largest if list[largest] > list[index] else index

            if largest == index:
                break
            list[largest],list[index] = list[index],list[largest]
            index = largest
            left = index*2+1


if __name__ == '__main__':
    list = [5,6,2,1,8,2,0,3,8]
    hs = HeapSort()
    hs.heapSort(list)
    print(list)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章