堆儲存 堆排序 python實現

2021-08-20 06:03:24 字數 4688 閱讀 4237

|—使用堆實現優先佇列:

對於總共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.實現堆排序時...