From 2d302469d58224ffa3b0ef7ff5983fc240acddeb Mon Sep 17 00:00:00 2001 From: Krzysztof Wojtas Date: Tue, 1 Oct 2024 23:58:24 +0200 Subject: [PATCH] #67 min_heapify --- src/solutions/chapter6/__init__.py | 0 src/solutions/chapter6/section2/__init__.py | 0 src/solutions/chapter6/section2/exercise3.py | 25 ++++++++++++ test/test_solutions/test_chapter6.py | 40 ++++++++++++++++++++ 4 files changed, 65 insertions(+) create mode 100644 src/solutions/chapter6/__init__.py create mode 100644 src/solutions/chapter6/section2/__init__.py create mode 100644 src/solutions/chapter6/section2/exercise3.py create mode 100644 test/test_solutions/test_chapter6.py diff --git a/src/solutions/chapter6/__init__.py b/src/solutions/chapter6/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/solutions/chapter6/section2/__init__.py b/src/solutions/chapter6/section2/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/solutions/chapter6/section2/exercise3.py b/src/solutions/chapter6/section2/exercise3.py new file mode 100644 index 0000000..ae5f0d2 --- /dev/null +++ b/src/solutions/chapter6/section2/exercise3.py @@ -0,0 +1,25 @@ +from book.chapter6.section1 import left +from book.chapter6.section1 import right + + +def min_heapify(A, i: int) -> None: + """Restores the min-heap property violated by a single node. + + Implements: + Min-Heapify + + Args: + A: the array representing a min-heap in which the min-heap property is violated by a single node + i: the index of the node in A that is not smaller than either of its children + """ + l = left(i) + r = right(i) + if l <= A.heap_size and A[l] < A[i]: + smallest = l + else: + smallest = i + if r <= A.heap_size and A[r] < A[smallest]: + smallest = r + if smallest != i: + A[i], A[smallest] = A[smallest], A[i] + min_heapify(A, smallest) diff --git a/test/test_solutions/test_chapter6.py b/test/test_solutions/test_chapter6.py new file mode 100644 index 0000000..37fbb59 --- /dev/null +++ b/test/test_solutions/test_chapter6.py @@ -0,0 +1,40 @@ +from hypothesis import given +from hypothesis import strategies as st +from hypothesis.strategies import integers +from hypothesis.strategies import lists + +from book.chapter6.section1 import build_max_heap +from book.data_structures import Array +from solutions.chapter6.section2.exercise3 import min_heapify +from test_case import ClrsTestCase +from test_util import create_array +from util import range_of + + +def build_min_heap_by_inversion(A: Array, n: int) -> None: + """Relies on the fact that when we replace each element of a max heap by the element's opposite, the resulting array + is a min heap.""" + build_max_heap(A, n) + for i in range_of(1, to=n): + A[i] = -A[i] + + +class TestChapter6(ClrsTestCase): + + @given(st.data()) + def test_min_heapify(self, data): + elements = data.draw(lists(integers(), min_size=1)) + n = len(elements) + A = create_array([-x for x in elements]) + build_min_heap_by_inversion(A, n) + self.assertMinHeap(A) + new_root = data.draw(integers(max_value=A[1] - 1)) + elements.remove(A[1]) + elements.append(new_root) + A[1] = new_root # possibly violate the min-heap property at the root + + min_heapify(A, 1) + + self.assertEqual(A.heap_size, n) + self.assertMinHeap(A) + self.assertArrayPermuted(A, elements, end=n)