|—使用堆實現優先佇列:
對於總共n個請求 使用普通陣列或者順序陣列 最差情況o(n^2)
使用堆 o(n*log n)
|-堆的基本實現
二叉堆:任何乙個子節點都不大於他的父節點
必須是一棵完全二叉樹
用陣列儲存二叉堆:
|-shift up
|-shift down
|-基礎堆排序
heapsort1
|-heapify 堆排序
建堆的過程直接構建 不用挨個元素插入
新建乙個堆的建構函式 , 傳入乙個陣列arr 和 該陣列長度n
|-原地堆排序
堆的索引從陣列下標0開始
無需額外的空間
parent(i) = (i-1)/2
left child(i) = 2*i +1
right child(i) = 2*i +2
源**:
import random
import numpy as np
import datetime
def gennearlyorderarray(n, swaptimes):
arr = list(range(n))
for i in range(swaptimes):
x = random.randint(0, n)
y = random.randint(0, n)
swap(arr, x, y)
return arr
def genrandomarray(n, start=0, end=10000):
return np.random.randint(start, end, size=n)
def atestsort(sortname, arr, n):
t_start = datetime.datetime.now()
sortname(arr, n)
t_end = datetime.datetime.now() # 記錄函式結束時間)
long = (t_end - t_start).total_seconds()
if issorted(arr, n):
print("sortname: %s, time: %f s" % (sortname.__name__, long))
else:
print('sort error!')
def swap(arr, i, j):
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
def issorted(arr, n):
for i in range(n - 1):
if (arr[i] > arr[i + 1]):
return false
return true
from tools import *
import sorting_advanced
class maxheap:
def __init__(self):
self.__data = [0]
self.__count = 0
# 建構函式 給定乙個陣列建立乙個最大堆 時間複雜度o(n)
def buildheap(self, arr):
n = len(arr)
self.__count = n
self.__data = [0]
self.__data.extend(arr)
for i in range(n // 2):
index = n // 2 - i
self.__shiftdown(index)
def size(self):
return self.__count
def isempty(self):
return self.__count == 0
def __swap(self, i, j):
temp = self.__data[i]
self.__data[i] = self.__data[j]
self.__data[j] = temp
# 最大堆核心輔助函式
def __shiftup(self, k):
while (k > 1) and (self.__data[(k // 2)] < self.__data[k]):
self.__swap(k // 2, k)
k = k // 2
def insert(self, item):
self.__count += 1
self.__shiftup(self.__count)
def __shiftdown(self, k):
# 判斷有無左孩子
while (2 * k <= self.__count):
j = 2 * k # 在此輪迴圈中 data[k] 與 data[j] 交換位置
if (j + 1 <= self.__count and self.__data[j + 1] > self.__data[j]):
j += 1
if (self.__data[k] >= self.__data[j]):
break
self.__swap(k, j)
k = j
# 從隊中去除堆頂元素 即堆中所儲存的最大元素
def extractmax(self):
if self.__count <= 0:
raise indexerror
ret = self.__data[1]
self.__swap(1, self.__count)
self.__data.pop(self.__count)
self.__count -= 1
self.__shiftdown(1)
return ret
def heapsort1(arr, n):
maxheap = maxheap()
for i in range(n):
maxheap.insert(arr[i])
for i in range(n):
index = n - 1 - i
arr[index] = maxheap.extractmax()
def heapsort2(arr, n):
maxheap = maxheap()
maxheap.buildheap(arr)
for i in range(n):
index = n - 1 - i
arr[index] = maxheap.extractmax()
def __shiftdown2(arr, n, k):
temp = arr[k]
# 判斷有無孩子
while (2 * k + 1 <= n - 1):
j = 2 * k + 1
if j + 1 < n and arr[j + 1] > arr[j]:
j += 1
if temp >= arr[j]:
break
arr[k] = arr[j]
k = j
arr[k] = temp
# 原地堆排序
def heapsort(arr, n):
# 從最後乙個非葉子節點開始 n-1-1 // 2
for i in range((n - 1 - 1) // 2, -1, -1):
__shiftdown2(arr, n, i)
for i in range(n - 1, 0, -1):
swap(arr, i, 0)
__shiftdown2(arr, i, 0)
if __name__ == '__main__':
# # 測試堆的資料結構
# maxheap = maxheap()
# print(maxheap.size())
# for i in range(50):
# a = random.randint(0, 100)
# maxheap.insert(a)
# # print(a)
## while(maxheap.size() != 0):
# num = maxheap.extractmax()
# print(num)
n = 100000
start = 0
end = 100000
# arr = gennearlyorderarray(n, swaptimes=100)
arr = genrandomarray(n, start, end)
arr2 = arr.copy()
arr3 = arr.copy()
arr4 = arr.copy()
arr5 = arr.copy()
atestsort(heapsort1, arr, n)
atestsort(heapsort2, arr2, n)
atestsort(sorting_advanced.quicksort2, arr3, n)
atestsort(sorting_advanced.quicksort3ways, arr4, n)
atestsort(heapsort, arr5, n)
堆排序python實現 堆排 python實現堆排
一 堆 完全二叉樹 堆排序是利用堆這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為o nlogn 是不穩定排序 堆排序中的堆有大頂堆 小頂堆兩種。他們都是完全二叉樹 將該堆按照排序放入列表 1.大頂堆 所有的父節點的值都比孩子節點大,葉子節點值最小。roo...
python3堆排序 python 堆排序
堆排序 堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點 但是不保證所有左子樹比右子樹小反之亦然 堆排序可以說是一種利用堆的概念來排序的選擇排序。分為兩種方法 大頂堆 每個...
堆以及堆排序實現
1.今天實現了一下堆排序,這裡的堆是指二叉堆,至於二項堆和斐波那契堆以後再說。先看二叉堆的定義 二叉堆是完全二叉樹或近似完全二叉樹。滿足特性是 父親節點的值大於等於 小於等於 左右孩子的值,並且左右子樹也是二叉堆。對應的二叉堆是大頂堆 小頂堆 二叉堆是完全二叉樹,可以用線性表來儲存。2.實現堆排序時...