1+ from __future__ import annotations
2+
13import random
24from typing import Union
35
1113from book .data_structures import CT
1214from book .data_structures import Heap
1315from book .data_structures import KeyObject
16+ from book .data_structures import T
1417from solutions .chapter6 .problem2 import multiary_child
1518from solutions .chapter6 .problem2 import multiary_parent
1619from solutions .chapter6 .section2 .exercise3 import min_heapify
1720from solutions .chapter6 .section2 .exercise6 import iterative_max_heapify
1821from solutions .chapter6 .section5 .exercise10 import max_heap_delete
22+ from solutions .chapter6 .section5 .exercise11 import SortedList
23+ from solutions .chapter6 .section5 .exercise11 import SortedListNode
24+ from solutions .chapter6 .section5 .exercise11 import merge_sorted_lists
1925from solutions .chapter6 .section5 .exercise3 import min_heap_decrease_key
2026from solutions .chapter6 .section5 .exercise3 import min_heap_extract_min
2127from solutions .chapter6 .section5 .exercise3 import min_heap_insert
2834from solutions .chapter6 .section5 .exercise9 import min_heap_dequeue
2935from solutions .chapter6 .section5 .exercise9 import min_heap_enqueue
3036from test_case import ClrsTestCase
37+ from test_util import create_array
3138from test_util import create_heap
3239from test_util import create_priority_queue
3340from util import range_of
@@ -44,6 +51,30 @@ def build_min_heap_by_inversion(A: Union[Heap[CT], Heap[KeyObject]], n: int) ->
4451 A [i ] = - A [i ]
4552
4653
54+ def create_sorted_list (elements : list [T ]) -> SortedList [T ]:
55+ sortedList = SortedList [T ]()
56+ tail = None
57+ for element in elements :
58+ x = SortedListNode [T ]()
59+ x .key = element
60+ if sortedList .head is None :
61+ sortedList .head = x
62+ tail = x
63+ else :
64+ tail .next = x
65+ tail = x
66+ return sortedList
67+
68+
69+ def convert_sorted_list (sorted_list : SortedList [T ]) -> list [T ]:
70+ result = []
71+ x = sorted_list .head
72+ while x is not None :
73+ result .append (x .key )
74+ x = x .next
75+ return result
76+
77+
4778class TestChapter6 (ClrsTestCase ):
4879
4980 @given (st .data ())
@@ -261,6 +292,26 @@ def test_max_heap_increase_key_(self, data):
261292 self .assertArrayPermuted (A , key_objects , end = n )
262293 self .assertPriorityQueueMappingConsistent (A )
263294
295+ @given (st .data ())
296+ def test_max_heap_increase_key__invalid_key (self , data ):
297+ keys = data .draw (lists (integers (), min_size = 1 ))
298+ key_objects = [KeyObject (key , data .draw (text ())) for key in keys ]
299+ heap = create_heap (key_objects )
300+ n = len (key_objects )
301+ build_max_heap (heap , n )
302+ A = create_priority_queue (heap , n )
303+ x = random .choice (key_objects )
304+ k = x .key - data .draw (integers (min_value = 1 ))
305+
306+ with self .assertRaisesRegex (ValueError , "new key is smaller than current key" ):
307+ max_heap_increase_key_ (A , x , k )
308+
309+ self .assertNotEquals (x .key , k )
310+ self .assertMaxHeap (A )
311+ self .assertEqual (A .heap_size , n )
312+ self .assertArrayPermuted (A , key_objects , end = n )
313+ self .assertPriorityQueueMappingConsistent (A )
314+
264315 @given (st .data ())
265316 def test_min_heap_queue (self , data ):
266317 # simulate the queue - enqueue, dequeue, then again enqueue and dequeue
@@ -350,24 +401,22 @@ def test_max_heap_delete(self, data):
350401 self .assertPriorityQueueMappingConsistent (A )
351402
352403 @given (st .data ())
353- def test_max_heap_increase_key__invalid_key (self , data ):
354- keys = data .draw (lists (integers (), min_size = 1 ))
355- key_objects = [KeyObject (key , data .draw (text ())) for key in keys ]
356- heap = create_heap (key_objects )
357- n = len (key_objects )
358- build_max_heap (heap , n )
359- A = create_priority_queue (heap , n )
360- x = random .choice (key_objects )
361- k = x .key - data .draw (integers (min_value = 1 ))
362-
363- with self .assertRaisesRegex (ValueError , "new key is smaller than current key" ):
364- max_heap_increase_key_ (A , x , k )
365-
366- self .assertNotEquals (x .key , k )
367- self .assertMaxHeap (A )
368- self .assertEqual (A .heap_size , n )
369- self .assertArrayPermuted (A , key_objects , end = n )
370- self .assertPriorityQueueMappingConsistent (A )
404+ def test_merge_sorted_lists (self , data ):
405+ k = data .draw (integers (min_value = 1 , max_value = 10 ))
406+ sorted_lists = [create_sorted_list (data .draw (lists (integers (), min_size = 1 , max_size = 10 ).map (sorted )))
407+ for _ in range_of (1 , to = k )]
408+ sorted_lists_array = create_array (sorted_lists )
409+ all_elements = []
410+ for sorted_list in sorted_lists :
411+ all_elements .extend (convert_sorted_list (sorted_list ))
412+
413+ actual_merged_list = merge_sorted_lists (sorted_lists_array , k )
414+
415+ actual_all_elements = convert_sorted_list (actual_merged_list )
416+ actual_all_elements_array = create_array (actual_all_elements )
417+ n = len (all_elements )
418+ self .assertArraySorted (actual_all_elements_array , end = n )
419+ self .assertArrayPermuted (actual_all_elements_array , all_elements , end = n )
371420
372421 @given (st .data ())
373422 def test_multiary_parent_child (self , data ):
0 commit comments