Created
April 30, 2018 08:48
-
-
Save lttzzlll/8520be5ba20b6c964c16a414ffb6c53a to your computer and use it in GitHub Desktop.
heap sort demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import unittest | |
def sift_down(lst, top, end): | |
pos = end | |
newitem = lst[pos] | |
while pos > top: | |
parentpos = (pos - 1) >> 1 | |
parent = lst[parentpos] | |
if newitem < parent: | |
lst[pos] = parent | |
pos = parentpos | |
continue | |
else: | |
break | |
lst[pos] = newitem | |
def sift_up(lst, top): | |
pos, end = top, len(lst) | |
newitem = lst[pos] | |
childpos = (pos << 1) + 1 | |
while childpos < end: | |
rightpos = childpos + 1 | |
if rightpos < end and lst[rightpos] < lst[childpos]: | |
childpos = rightpos | |
lst[pos] = lst[childpos] | |
pos = childpos | |
childpos = (pos << 1) + 1 | |
lst[pos] = newitem | |
sift_down(lst, top, pos) | |
def heapify(lst): | |
for i in reversed(range(len(lst) >> 1)): | |
sift_up(lst, i) | |
def heap_pop(lst): | |
lastitem = lst.pop() | |
if lst: | |
returnitem = lst[0] | |
lst[0] = lastitem | |
sift_up(lst, 0) | |
return returnitem | |
return lastitem | |
def heap_push(lst, item): | |
lst.append(item) | |
sift_down(lst, 0, len(lst)-1) | |
def heap_sort(lst): | |
heapify(lst) | |
res = [] | |
while lst: | |
res.append(heap_pop(lst)) | |
return res | |
class HeapqTest(unittest.TestCase): | |
def setUp(self): | |
import random | |
self.heap = random.sample(range(0, 100), 15) | |
def test_heapify(self): | |
print('before sort: ', self.heap) | |
sorted_heap = sorted(self.heap) | |
heap_sorted_heap = heap_sort(self.heap) | |
print('after sort:', sorted_heap) | |
print('heap sort:', heap_sorted_heap) | |
self.assertListEqual(sorted_heap, heap_sorted_heap) | |
def test_heap_push(self): | |
print('before sort:', self.heap) | |
sorted_heap = sorted(self.heap) | |
print('after sort:', sorted_heap) | |
heap = [] | |
for i in self.heap: | |
heap_push(heap, i) | |
res = [] | |
while heap: | |
res.append(heap.pop()) | |
print('heap sort:', res) | |
def tearDown(self): | |
self.heap = None | |
if __name__ == '__main__': | |
unittest.main() | |
``` | |
Result: | |
``` | |
before sort: [66, 16, 2, 86, 55, 12, 64, 32, 8, 71, 22, 77, 10, 25, 74] | |
after sort: [2, 8, 10, 12, 16, 22, 25, 32, 55, 64, 66, 71, 74, 77, 86] | |
heap sort: [74, 64, 16, 77, 66, 71, 55, 86, 25, 12, 22, 32, 10, 8, 2] | |
.before sort: [84, 87, 42, 30, 79, 55, 2, 71, 1, 91, 66, 70, 5, 75, 54] | |
after sort: [1, 2, 5, 30, 42, 54, 55, 66, 70, 71, 75, 79, 84, 87, 91] | |
heap sort: [1, 2, 5, 30, 42, 54, 55, 66, 70, 71, 75, 79, 84, 87, 91] | |
. | |
---------------------------------------------------------------------- | |
Ran 2 tests in 0.007s | |
OK | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
在最小堆上获取nlargest元素的操作。