python3堆排序_Pythonの堆排序(最小堆)

1.[代码][Python]代码

# -*- coding: utf-8 -*-

def parent(i):

"""父结点下标"""

return int((i - 1) >> 1); # floor((i-1)/2)

def left(i):

"""左儿子下标"""

return (i << 1) + 1; # 2i + 1

def right(i):

"""右儿子下标"""

return (i << 1) + 2; # 2i + 2

def min_heapify(A, i, heap_size, offset=0):

"""最小堆化A[i]为根的子树,伪码如下:

MIN-HEAPIFY(A, i)

1 l ← LEFT(i)

2 r ← RIGHT(i)

3 if l <= heap-size[A] and A[l] < A[i] // A[i],A[LEFT[A]]中找出最小的

4 then least ← l

5 else least ← i

6 if r <= heap-size[A] and A[r] < A[least] // A[i],A[LEFT[A]],A[RIGHT[i]]中找出最小的

7 then least ← r

8 if least != i // A[i]为最小时结束,否则继续递归

9 then exchange A[i] ↔ A[least] // 交换A[i],A[least],使得满足最小堆性质

10 MIN-HEAPIFY(A, least) // 递归

# 注:上述下标是从1开始的,编程时都从0开始了。

T(n) = O(lgn)

Args:

A (Sequence): 序列A

i (int): 下标i

heap_size (int): 存放在A中的堆元素个数

offset (int): 取值偏移量(只用在了heap_sort)

"""

l, r = left(i), right(i)

if l < heap_size and A[l + offset] < A[i + offset]:

least = l

else:

least = i

if r < heap_size and A[r + offset] < A[least + offset]:

least = r

if least != i:

A[i + offset], A[least + offset] = A[least + offset], A[i + offset]

min_heapify(A, least, heap_size, offset)

def build_min_heap(A):

"""构造成最小堆,伪码如下:

BUILD-MIN-HEAP(A)

1 heap-size[A] ← length[A] // 堆元素个数为数组大小

2 for i ← floor(length[A]/2) downto 1 // 自最后个父结点向上

3 do MIN-HEAPIFY(A, i) // 最小堆化A[i]为根的子树

T(n) = O(n)

Args:

A (Sequence): 序列A

"""

heap_size = len(A)

parent_last = parent(heap_size - 1) # 最后一个下标的父结点

for i in range(parent_last, -1, -1): # parent_last downto 0

min_heapify(A, i, heap_size)

def heap_sort_reverse(A):

"""堆排序(逆序),伪码如下:

HEAPSORT-REVERSE(A)

1 BUILD-MIN-HEAP(A) // 构造成最小堆

2 for i ← length[A] downto 2

3 do exchange A[1] ↔ A[i] // 最小元素A[1]与A[n]互换

4 heap-size[A] ← heap-size[A] - 1 // 减小heap-size[A]

5 MIN-HEAPIFY(A, 1) // 保持最小堆性质

T(n) = O(nlgn)

Args:

A (Sequence): 序列A

"""

build_min_heap(A)

heap_size = len(A)

for i in range(heap_size - 1, 0, -1):

A[0], A[i] = A[i], A[0]

heap_size -= 1

min_heapify(A, 0, heap_size)

def heap_sort(A):

"""堆排序,伪码如下:

HEAPSORT(A)

1 for i ← 1 to length[A] - 1 // 从第一位到倒数第二位

2 sub_heap_size = length[A] - i + 1 // i开始的子树的堆大小

3 for j ← floor(sub_heap_size/2) downto 1 // 从子树最后个父结点向上,以将该子树构造成最小堆

4 do MIN-HEAPIFY(A[i..length[A]], j) // 让i开始的子树的j为根的子树保持最小堆性质

T(n) = O(n^2)

Args:

A (Sequence): 序列A

"""

heap_size = len(A)

for i in range(0, heap_size - 1):

sub_heap_size = heap_size - i # 子树堆大小

sub_p_last = parent(sub_heap_size - 1) # 子树坐标的最后个父结点

for j in range(sub_p_last, -1, -1):

min_heapify(A, j, sub_heap_size, i) # i为子树在A中的偏移量

def heap_sort2(A):

"""亦可在heap_sort_reverse时,拼接正序结果,其T(n) = O(nlgn)。

或者,由heap_sort_reverse获得逆序结果后reversed,线性时间即可。

这两种方式,相较于heap_sort都要好很多。

"""

build_min_heap(A)

heap_size = len(A)

R = []

for i in range(heap_size - 1, 0, -1):

R.append(A[0])

A[0], A[i] = A[i], A[0]

heap_size -= 1

min_heapify(A, 0, heap_size)

R.append(A[0])

return R

if __name__ == '__main__':

import random, timeit

items = range(1000)

random.shuffle(items)

def test_heap_sort():

print(items)

heap_sort(items)

print(items)

def test_heap_sort_reverse():

print(items)

heap_sort_reverse(items)

print(items)

test_methods = [test_heap_sort, test_heap_sort_reverse]

for test in test_methods:

name = test.__name__ # test.func_name

t = timeit.Timer(name + '()', 'from __main__ import ' + name)

print(name + ' takes time : %f' % t.timeit(1))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值