
"""simple docstring"""

from __future__ import annotations

from abc import abstractmethod
from collections.abc import Iterable
from typing import Generic, Protocol, TypeVar

class __lowerCAmelCase						( lowerCAmelCase_     ):





     @abstractmethod
     def __lt__(      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      pass





     @abstractmethod
     def __gt__(      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      pass







     @abstractmethod
     def __eq__(      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      pass


UpperCamelCase      :							Optional[int]          =					TypeVar("T", bound=Comparable)

class __lowerCAmelCase						( Generic[T]     ):





     def __init__(      self ):

      '''simple docstring'''




      __UpperCamelCase							    =			[]
      __UpperCamelCase							    =			0





     def __repr__(      self ):

      '''simple docstring'''




      return str(self.h )





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      if child_idx > 0:
       return (child_idx - 1) // 2
      return None





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      __UpperCamelCase							    =			2 * parent_idx + 1
      if left_child_index < self.heap_size:
       return left_child_index
      return None





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      __UpperCamelCase							    =			2 * parent_idx + 2
      if right_child_index < self.heap_size:
       return right_child_index
      return None





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      if index < self.heap_size:
       __UpperCamelCase							    =			index
       __UpperCamelCase							    =			self.left_child_idx(lowerCamelCase_ )
       __UpperCamelCase							    =			self.right_child_idx(lowerCamelCase_ )
       # check which child is larger than its parent
       if left_child is not None and self.h[left_child] > self.h[violation]:
        __UpperCamelCase							    =			left_child
       if right_child is not None and self.h[right_child] > self.h[violation]:
        __UpperCamelCase							    =			right_child
       # if violation indeed exists
       if violation != index:
        # swap to fix the violation
        __UpperCamelCase							    =			self.h[index], self.h[violation]
        # fix the subsequent violation recursively if any
        self.max_heapify(lowerCamelCase_ )





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      __UpperCamelCase							    =			list(lowerCamelCase_ )
      __UpperCamelCase							    =			len(self.h )
      if self.heap_size > 1:
       # max_heapify from right to left but exclude leaves (last level)
       for i in range(self.heap_size // 2 - 1      ,	-1      ,	-1 ):
        self.max_heapify(lowerCamelCase_ )





     def 		UpperCAmelCase   (      self ):

      '''simple docstring'''




      if self.heap_size >= 2:
       __UpperCamelCase							    =			self.h[0]
       __UpperCamelCase							    =			self.h.pop(-1 )
       self.heap_size -= 1
       self.max_heapify(0 )
       return me
      elif self.heap_size == 1:
       self.heap_size -= 1
       return self.h.pop(-1 )
      else:
       raise Exception('Empty heap' )





     def 		UpperCAmelCase   (      self      ,	__UpperCAmelCase ):

      '''simple docstring'''




      self.h.append(lowerCamelCase_ )
      __UpperCamelCase							    =			(self.heap_size - 1) // 2
      self.heap_size += 1
      while idx >= 0:
       self.max_heapify(lowerCamelCase_ )
       __UpperCamelCase							    =			(idx - 1) // 2







     def 		UpperCAmelCase   (      self ):

      '''simple docstring'''




      __UpperCamelCase							    =			self.heap_size
      for j in range(size - 1      ,	0      ,	-1 ):
       __UpperCamelCase							    =			self.h[j], self.h[0]
       self.heap_size -= 1
       self.max_heapify(0 )
      __UpperCamelCase							    =			size


if __name__ == "__main__":
      import doctest

      # run doc test
      doctest.testmod()

      # demo
      for unsorted in [
          [0],
          [2],
          [3, 5],
          [5, 3],
          [5, 5],
          [0, 0, 0, 0],
          [1, 1, 1, 1],
          [2, 2, 3, 5],
          [0, 2, 2, 3, 5],
          [2, 5, 3, 0, 2, 3, 0, 3],
          [6, 1, 2, 7, 9, 3, 4, 5, 1_0, 8],
          [1_0_3, 9, 1, 7, 1_1, 1_5, 2_5, 2_0_1, 2_0_9, 1_0_7, 5],
          [-4_5, -2, -5],
      ]:
            print(f'''unsorted array: {unsorted}''')

            UpperCamelCase      :							Dict          =					Heap()
            heap.build_max_heap(unsorted)
            print(f'''after build heap: {heap}''')

            print(f'''max value: {heap.extract_max()}''')
            print(f'''after max value removed: {heap}''')

            heap.insert(1_0_0)
            print(f'''after new value 100 inserted: {heap}''')

            heap.heap_sort()
            print(f'''heap-sorted array: {heap}\n''')







__lowerCamelCase   	=  {0: [1, 2], 1: [0, 3], 2: [0], 3: [1], 4: [5, 6], 5: [4, 6], 6: [4, 5]}

__lowerCamelCase   	=  {0: [1, 2, 3], 1: [0, 3], 2: [0], 3: [0, 1], 4: [], 5: []}



def 			_a      (    __UpperCamelCase	,	__UpperCamelCase	,	__UpperCamelCase			):
     a_     :  Tuple				      =     True
     a_     :  Optional[Any]				      =     []

     for neighbour in graph[vert]:
          if not visited[neighbour]:
               connected_verts += dfs(__UpperCamelCase	,	__UpperCamelCase	,	__UpperCamelCase			)

     return [vert, *connected_verts]



def 			_a      (    __UpperCamelCase			):
     a_     :  Dict				      =     len(__UpperCamelCase			)
     a_     :  List[str]				      =     graph_size * [False]
     a_     :  Dict				      =     []

     for i in range(__UpperCamelCase			):
          if not visited[i]:
               a_     :  str				      =     dfs(__UpperCamelCase	,	__UpperCamelCase	,	__UpperCamelCase			)
               components_list.append(__UpperCamelCase			)

     return components_list


if __name__ == "__main__":
       import doctest

       doctest.testmod()



