一直想把常見的排序演算法,都寫一遍。今天,終於完成了。打卡之堆排序。
堆排序演算法,主要利用到完全二叉數以及大根堆的概念。完全二叉數: 若設二叉樹的深度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第 h 層所有的結點都連續集中在最左邊,這就是完全二叉樹。 大根堆:任何一顆子樹的最大值都是它本身。
通常情況下,如果你理解了完全二叉數的概念,那麼完全二叉數就可以用乙個陣列來進行表示。
如果用陣列表示完全二叉數的話,假設下標為i的元素,那麼它的左孩子:2*i+1 右孩子為2*i+2 它的父節點為(i-1)//2
ok,那我先來看看大根堆是如何實現的:
def heapinsert(alist, i):
while alist[i] > alist[(i-1)//2] and i!=0:
alist[i], alist[(i-1)//2] = alist[(i-1)//2], alist[i]
i = (i - 1) // 2
nums=[1,3,5,4,2,6]
for i in range(len(nums)):
heapinsert(nums,i)
我們從下往上將每一顆子樹的根都調換成該子樹的最大值。eg:nums=[1,3,5,4,2,6] 變成:nums=[6,4,5,1,2,3]
相當於做一次大根堆的操作,我們就得到了完全二叉數中的最大值。那我們就可以對陣列每次操作大根堆,然後將下標為0的元素與陣列最後一位進行元素交換。那陣列中的最大值就得到了。 eg:nums=[6,4,5,1,2,3] 轉變以後 nums=[3,4,5,1,2,6]。但是這會破壞大根堆的有序性。所以,我們每交換一次,則需要對大根堆進行調整。這個時候我們需要將置換厚的元素從上到下與其左右孩子做比較,往下沉,重新得到乙個大根堆(注意,當我們將最大值交換以後,相當與陣列的長度減1,不考慮陣列末尾的值,因為此時末尾元素,已經排好序了,就是待排陣列的最大值)。
然後,我們來看看整體**:
def heapsort(alist):
length = len(alist)
#首先對陣列進行大根堆排序
for i in range(length):
heapinsert(alist, i)
for j in range(length-1, 0, -1):
#置換堆頂與樹末尾的值
alist[0], alist[j] = alist[j], alist[0]
#每次對前j-1個數重新進行大根堆排序
heapify(alist, 0, j-1)
def heapinsert(alist, i):
while alist[i] > alist[(i-1)//2] and i!=0:
alist[i], alist[(i-1)//2] = alist[(i-1)//2], alist[i]
i = (i - 1) // 2
def heapify(alist, index, size):
left = index*2+1#獲取當前節點的子節點
#限制陣列邊界,只排未排好序的陣列
while left <= size:
#獲取左右孩子較大值的下標
largest = left+1 if left+1 <= size and alist[left] < alist[left+1] else left
#獲取當前節點與左右孩子中最大值中較大值的下標
largest = index if alist[index] > alist[largest] else largest
#對比完,如果當前仍是最大值,則已符合大根堆,則退出此次迴圈
if largest == index:
break
#不然,使子樹中根的值最大
alist[largest], alist[index] = alist[index], alist[largest]
#將當前節點置為先前最大值的下標,繼續排序
index = largest
left = index*2+1
if __name__ == '__main__':
#獲取乙個整數陣列
nums = list(map(int, input().split()))
#對其進行排序
heapsort(nums)
print(nums)
堆排序的時間複雜度為 pyton3的數字操作你都會用嗎?
數字資料型別用於儲存數值。資料型別是不允許改變的,這就意味著如果改變量字資料型別的值,將重新分配空間。1.del 用於刪除一些數字物件的引用 2.整形 int 通常被稱為是整形或者整數,是正或負整數,不帶小數點。3.浮點型 float 浮點型由整數部分與小數部分組成。4.負數 complex 負數由...
堆排序 基於scala實現
堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。堆排序可以說是一種利用堆的概念來排序的選擇排序。分為兩種方法 大頂堆 每個節點的值都大於或等於其子節點的值,在堆排序演算法...
python3堆排序 python 堆排序
堆排序 堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點 但是不保證所有左子樹比右子樹小反之亦然 堆排序可以說是一種利用堆的概念來排序的選擇排序。分為兩種方法 大頂堆 每個...