import numpy as np
class heapsort(object):
# 這是堆中元素的個數
__count = 0
# 這是堆得最大容量
__capacity = 50
arr = [0]*__capacity
def __init__(self):
pass
def get_capacity(self):
return self.__capacity
def extend_capacity(self):
self.__capacity += 30
self.arr.extend([0]*30)
def get_count(self):
return self.__count
def init_heap(self, nums):
while self.get_capacity() + 1 < len(nums):
self.extend_capacity()
print("擴容+30 成功")
print(self.arr)
for i, item in enumerate(nums):
self.arr[i+1] = item
self.__count += 1
print("the count is {}".format(self.__count))
print("origin is :")
print(self.arr)
self.adjust()
print("init_heap result is :")
print(self.arr)
# 從第乙個位置開始, 調整堆
# 判斷左右節點是否存在, 若存在並且子節點大於父節點,那麼交換,
# 繼續向下進行, 直到不滿足條件終止
def shift_down(self, pos):
j = 2*pos
while j <= self.get_count():
# 如果右邊節點存在
if j + 1 <= self.get_count():
if self.arr[j+1] > self.arr[j]:
j = j + 1
if self.arr[pos] < self.arr[j]:
self.arr[pos], self.arr[j] = self.arr[j], self.arr[pos]
pos = j
j = 2*j
else:
break
def adjust(self):
n = self.get_count() // 2
while n >= 1:
self.shift_down(n)
n -= 1
# adjust_count = self.get_count() // 2
# n = adjust_count
# while adjust_count >= 1:
# # j代表著要被交換的哪乙個
# j = n*2
# while 2*n <= self.__count:
# # 挑選兩者之中最大的乙個
# if j+1 <= self.__count and self.arr[j+1] > self.arr[j]:
# j = j + 1
# if self.arr[j] > self.arr[n]:
# self.arr[j], self.arr[n] = self.arr[n], self.arr[j]
# n = j
# j = j*2
# else:
# break
# adjust_count -= 1
def is_big_heap(self):
n = self.get_count() // 2
while n >= 1:
if self.arr[n] >= self.arr[2*n]:
if 2*n + 1 <= self.get_count():
if self.arr[n] >= self.arr[2*n+1]:
n -= 1
continue
else:
return false
else:
return false
n -= 1
return true
# 去除最大的乙個數, 然後調整堆為大頂堆
def get_max(self):
max_num = self.arr[1]
self.arr[1], self.arr[self.get_count()] = self.arr[self.get_count()], self.arr[1]
self.__count -= 1
self.adjust()
# print("after get_max: ")
# print(self.arr)
# print(self.is_big_heap())
return max_num
def heap_sort(self):
res = [0]*self.get_count()
while self.get_count() > 0:
print("heap_sort result is :")
print(res[::-1])
def insert(self, num):
if self.__capacity <= self.__count:
self.extend_capacity()
self.__count = self.get_count() + 1
self.arr[self.__count] = num
self.arr[self.__count], self.arr[1] = self.arr[self.__count], self.arr[1]
self.adjust()
print("afet insert :\n{}".format(self.arr))
def print_heap(self):
print("heap status is :")
print(self.arr)
if __name__ == '__main__':
nums = np.random.randint(0, 100, 20)
print(nums)
heap1 = heapsort()
heap1.init_heap(nums)
heap1.insert(55)
print("is a big_heap ? : {}".format(heap1.is_big_heap()))
heap1.heap_sort()
heap1.print_heap()
手寫堆排序
堆排序是乙個不穩定排序但是其最好最壞的時間複雜度為nlogn。所謂的堆其實就是乙個完全二叉樹的結構其主要特點是所有的子樹中父節點一定大於子節點。堆排的主要思想是將序列構造成乙個大頂堆,堆頂一定是整個序列中最大值然後將最大值與最後乙個數值交換,之後又將剩下的n 1個元素構造成乙個大頂堆之後在依次向與之...
手寫堆排序和歸併排序
手動實現堆排序,使用大根堆實現 從小到大排序 完成在陣列 low,high 的範圍內,對在位置low上的節點向下進行調整 void shift int nums,int low,int high else break nums i tmp void heap sort int nums,int n ...
面試題 手寫堆排序
前言 因為是面對面試場景,所以原理什麼的就不講,網上一搜一大把,假設看到這篇部落格的人都會堆排序的原理了。我就大概的用最簡單的 實現了下。畢竟面試這麼乙個水題寫半個小時也不太好吧。實現中遇到的困難 陣列下標必須要從0開始 0 對應左右節點 1,2 如果從1 開始 對應 3,4 2對應 5,6 那麼1...