Starting from:

$30

CS261-Data Structures Solved

This  method  returns a   number  of  empty  buckets  in  the  hash  table.  

  

Example  #1:  

   m  =  HashMap(100, h ash_function_1)     print(m.empty_buckets(),  m.size,  m.capacity)     m.put('key1', 1 0)     print(m.empty_buckets(),  m.size,  m.capacity)     m.put('key2', 2 0)     print(m.empty_buckets(),  m.size,  m.capacity)     m.put('key1', 3 0)     print(m.empty_buckets(),  m.size,  m.capacity)     m.put('key4', 4 0)  

   print(m.empty_buckets(),  m.size,  m.capacity)  

 

  Output:     

   100  0  100  

   99  1  100  

   98  2  100  

   98  2  100  

   97  3  100  

  

  

Example  #2:  

   #  this  test  assumes  that  put()  has  already  been  correctly  implemented     m  =  HashMap(50,  hash_function_1)         for  i  in  range(150):  

           m.put('key'  +  str(i),  i  *  100)             if  i  %  30  ==  0:  

               print(m.empty_buckets(),  m.size,  m.capacity)  

 

  Output:        49  1  50  

   39  31  50  

   36  61  50  

   33  91  50  

   30  121  50  

 

  

            

table_load (self)  ->  float:   

  

This  method  returns t he  current  hash  table  load  factor.  

  Example  #1:  

   m  =  HashMap(100, h ash_function_1)     print(m.table_load())     m.put('key1', 1 0)     print(m.table_load())     m.put('key2', 2 0)     print(m.table_load())     m.put('key1', 3 0)     print(m.table_load())  

 

  Output:     

   0.0  

   0.01  

   0.02  

   0.02  

 

 Example  #2:  

   m  =  HashMap(50,  hash_function_1)         for  i  in  range(50):  

           m.put('key'  +  str(i),  i  *  100)             if  i  %  10  ==  0:  

               print(m.table_load(),  m.size,  m.capacity)  

 

  Output:     

   0.02  1  50  

   0.22  11  50  

   0.42  21  50  

   0.62  31  50  

   0.82  41  50  

 

 

            

   clear (self)  ->  None:   

  

This  method  clears t he  content  of  the  hash  map.  It  does  not  change  underlying  hash  table  capacity.  

  

Example  #1:  

   m  =  HashMap(100, h ash_function_1)     print(m.size, m .capacity)     m.put('key1', 1 0)  

   m.put('key2', 2 0)  

   m.put('key1', 3 0)     print(m.size, m .capacity)     m.clear()  

   print(m.size, m .capacity)  

 

  Output    :   

   0  100  

   2  100  

   0  100  

 

  

Example  #2:  

   m  =  HashMap(50,  hash_function_1)     print(m.size, m .capacity)     m.put('key1', 1 0)     print(m.size, m .capacity)     m.put('key2', 2 0)     print(m.size, m .capacity)     m.resize_table(100)     print(m.size, m .capacity)     m.clear()  

   print(m.size, m .capacity)  

 

  Output    :   

0  50  

1  50  

2  50  

   2  100  

   0  100  

 
  

put (self,  key:  str,  value:  object)  ->  None:   

  

This  method  updates t he  key  /  value  pair  in  the  hash m ap.  If  a  given  key  already  exists  in the  hash  map,  its  associated  value  should  be  replaced  with  the  new  value.  If a   given  key  is  not  in  the  hash  map,  a  key  /  value  pair  should b e  added.  

  

Example  #1:  

   m  =  HashMap(50,  hash_function_1)     for  i  in  range(150):  

       m.put('str'  +  str(i),  i  *  100)         if  i  %  25 = =  24:  

           print(m.empty_buckets(),  m.table_load(),  m.size,  m.capacity)  

  

  Output:     

   39  0.5  25  50  

   37  1.0  50  50  

   35  1.5  75  50  

   32  2.0  100  50  

   30  2.5  125  50  

   30  3.0  150  50  

 

 

Example  #2:  

   m  =  HashMap(40,  hash_function_2)     for  i  in  range(50):  

       m.put('str'  +  str(i  //  3),  i  *  100)         if  i  %  10 = =  9:  

           print(m.empty_buckets(),  m.table_load(),  m.size,  m.capacity)  

  

  Output:     

   36  0.1  4  40  

   33  0.175  7  40  

   30  0.25  10  40  

   27  0.35  14  40     25  0.425  17  40  

            

contains_key (self,  key:  str)  ->  bool:   

  

This  method  returns T rue  if  the  given  key  is  in  the  hash  map,  otherwise  it  returns  False.  An empty  hash  map  does  not  contain  any  keys.  

  

Example  #1:  

   m  =  HashMap(50,  hash_function_1)     print(m.contains_key('key1'))     m.put('key1', 1 0)  

   m.put('key2', 2 0)  

   m.put('key3', 3 0)     print(m.contains_key('key1'))     print(m.contains_key('key4'))     print(m.contains_key('key2'))     print(m.contains_key('key3'))     m.remove('key3')     print(m.contains_key('key3'))  

 

  Output:     

   False  

   True  

   False  

   True  

   True  

   False  

 

 

Example  #2:  

   m  =  HashMap(75,  hash_function_2)     keys  =  [i  for i   in  range(1,  1000,  20)]     for  key  in  keys:  

       m.put(str(key),  key  *  42)     print(m.size, m .capacity)     result  =  True     for  key  in  keys:  

       #  all  inserted  keys  must  be  present         result  &= m .contains_key(str(key))         #  NOT  inserted  keys  must  be  absent         result  &= n ot  m.contains_key(str(key  +  1))     print(result)  

 

  Output:     

   50  75  

   True  

            

get (self,  key:  str)  ->  object:   

  

This  method  returns t he  value  associated  with  the  given  key.  If  the  key  is  not  in  the  hash map,  the  method  returns  None.  

  

Example  #1:  

   m  =  HashMap(30,  hash_function_1)     print(m.get('key'))     m.put('key1', 1 0)     print(m.get('key1'))   

  Output:     

   None  

   10  

 

  

Example  #2:  

   m  =  HashMap(150, h ash_function_2)     for  i  in  range(200,  300,  7):         m.put(str(i),  i  *  10)     print(m.size, m .capacity)     for  i  in  range(200,  300,  21):  

       print(i,  m.get(str(i)),  m.get(str(i))  ==  i  *  10)  

       print(i  + 1 ,  m.get(str(i  +  1)),  m.get(str(i  +  1))  ==  (i  +  1)  *  10)   

  Output:     

   15  150  

200  2000  True  

201  None  False  

221  2210  True  

222  None  False  

242  2420  True  

243  None  False  

263  2630  True  

264  None  False  

284  2840  True  

285  None  False  

            

remove (self,  key:  str)  ->  None:   

  

This  method  removes  the  given  key  and  its a ssociated  value  from  the  hash  map.  If  a  given key  is  not  in  the  hash m ap,  the  method  does  nothing  (no  exception  needs  to  be  raised).     

Example  #1:  

   m  =  HashMap(50,  hash_function_1)     print(m.get('key1'))     m.put('key1', 1 0)     print(m.get('key1'))     m.remove('key1')     print(m.get('key1'))     m.remove('key4')  

 

  Output:     

   None  

   10  

   None  



            

resize_table (self,  new_capacity:  int)  ->  None:   

  

This  method  changes t he  capacity  of  the  internal  hash  table.  All  existing  key  /  value  pairs must  remain  in  the  new  hash  map  and  all  hash  table  links  must  be  rehashed.  If  new_capacity  is  less  than  1,  this  method  should  do  nothing.  

  

Example  #1:  

   m  =  HashMap(20,  hash_function_1)     m.put('key1', 1 0)  

   print(m.size, m .capacity,  m.get('key1'),  m.contains_key('key1'))     m.resize_table(30)  

   print(m.size, m .capacity,  m.get('key1'),  m.contains_key('key1'))  

 

  Output:     

   1  20  10  True  

   1  30  10  True  

 

 

Example  #2:  

   m  =  HashMap(75,  hash_function_2)     keys  =  [i  for i   in  range(1,  1000,  13)]     for  key  in  keys:  

       m.put(str(key),  key  *  42)     print(m.size, m .capacity)  

    for  capacity  in  range(111,  1000,  117):         m.resize_table(capacity)  

       m.put('some  key',  'some  value')         result  =  m.contains_key('some  key')         m.remove('some  key')         for  key  in  keys:  

           result  &=  m.contains_key(str(key))             result  &=  not  m.contains_key(str(key  +  1))  

       print(capacity,  result,  m.size,  m.capacity,  round(m.table_load(), 2 ))   

  Output:     

   77  75  

   111  True  77  111  0.69  

   228  True  77  228  0.34  

   345  True  77  345  0.22  

   462  True  77  462  0.17  

   579  True  77  579  0.13  

   696  True  77  696  0.11  

   813  True  77  813  0.09  

   930  True  77  930  0.08          

 get_keys (self)  ->  DynamicArray:   

  

This  method  returns a   DynamicArray  that  contains  all  keys  stored  in  your  hash  map.  The  order  of  the  keys  in the     DA  does  not  matter.  

  

Example  #1:  

   m  =  HashMap(10,  hash_function_2)     for  i  in  range(100,  200,  10):  

       m.put(str(i),  str(i  *  10))     print(m.get_keys())  

 

   m.resize_table(1)     print(m.get_keys())  

 

   m.put('200',  '2000')  

   m.remove('100')  

   m.resize_table(2)     print(m.get_keys())  

 

  Output:     

   ['160',  '110',  '170',  '120',  '180',  '130',  '190',  '140',  '150',  '100']  

   ['100',  '150',  '140',  '190',  '130',  '180',  '120',  '170',  '110',  '160']     ['200',  '160',  '110',  '170',  '120',  '180',  '130',  '190',  '140',  '150']  

 

              

Part  2  -  Summary  and  Specific  Instructions  
  

1.     Implement  the  MinHeap  class  by  completing  provided  skeleton  code i n  the  file  min_heap.py .  Once  completed,  your  implementation  will  include  the  following  methods:  

 add()  get_min()  remove_min()  build_heap()  

 

2.     P rewritten  DynamicArray  class  is  provided  for  you  in  the  skeleton code    (file  a5_include.py ).  You  should  use  objects  of  this  class  in  your  MinHeap  class  implementation  for  storing  heap  content.    

3.     Prewritten  DynamicArray  class  may  provide  different f unctionality  than  that  described  in  the  lectures  or  implemented  in  prior  homework  assignments.  Review  docstrings  in  the  skeleton  code  to  understand  available  methods,  their  use, a nd  input  /  output  parameters.  

  

4.     The  number  of  objects  stored  in  the  MinHeap  will  be  between  0  and  1,000,000  inclusive.  

  

5.     RESTRICTIONS:  You  are  NOT a llowed  to  use  ANY  built-in  Python  data  structures  and/or  their  methods.  

  

You  are  NOT  allowed  to  directly  access  any  variables  of  the  DynamicArray  class.  All  work  must  be  done  only  by  using  class  methods.    

6.     Variables  in  the MinHeap     class  are  not  private.  You  ARE  allowed  to  access  and  change  their  values  directly.  You  do  not  need  to  write  any  getter  or  setter  methods  for  the  MinHeap  class.  

  

7.     You  may  assume  all  methods  of  the  provided  DynamicArray  class  have  O(1)  runtime  complexity.  

  

              

add (self,  node:  object)  ->  None:   

  

This  method  adds a   new  object  to  the  MinHeap  maintaining  heap  property.  

  

Runtime  complexity o f  this  implementation  must  be  O(logN).  

  

Example  #1:  

   h  =  MinHeap()     print(h,  h.is_empty())     for  value  in  range(300,  200,  -15):         h.add(value)         print(h)  

 

  Output:     

   HEAP  []  True  

   HEAP  [300]  

   HEAP  [285,  300]  

   HEAP  [270,  300,  285]  

   HEAP  [255,  270,  285,  300]  

   HEAP  [240,  255,  285,  300,  270]  

   HEAP  [225,  255,  240,  300,  270,  285]  

   HEAP  [210,  255,  225,  300,  270,  285,  240]  

 

 

Example  #2:     h  =  MinHeap(['fish',  'bird'])     print(h)     for  value  in  ['monkey',  'zebra',  'elephant',  'horse', ' bear']:         h.add(value)         print(h)  

 

  Output:     

   HEAP  ['bird', ' fish']  

   HEAP  ['bird', ' fish',  'monkey']  

   HEAP  ['bird', ' fish',  'monkey',  'zebra']  

   HEAP  ['bird', ' elephant',  'monkey',  'zebra',  'fish']  

   HEAP  ['bird', ' elephant',  'horse',  'zebra',  'fish',  'monkey']  

   HEAP  ['bear', ' elephant',  'bird',  'zebra',  'fish',  'monkey',  'horse']       

get_min (self)  ->  object:   

  

This  method  returns a n  object  with  a  minimum  key  without r emoving  it  from  the  heap.  If  the  heap  is  empty,  the  method r aises  a  MinHeapException.  

  

Runtime  complexity o f  this  implementation  must  be  O(1).  

  

Example  #1:     h  =  MinHeap(['fish',  'bird'])     print(h)  

   print(h.get_min(),  h.get_min())  

 

  Output:     

   HEAP  ['bird', ' fish']     bird  bird  

 

  remove_min (self)  ->  object:   

  

This  method  returns a n  object  with  a  minimum  key  and  removes  it  from  the  heap.  If  the  heap  is  empty,  the  method  raises  a  MinHeapException.   

  

Runtime  complexity o f  this  implementation  must  be  O(logN).  

  

Example  #1:  

   h  =  MinHeap([1,  10,  2,  9,  3,  8,  4,  7,  5,  6])     while  not  h.is_empty():         print(h,  end='  ')         print(h.remove_min())  

 

  Output:     

   HEAP  [1,  3,  2,  5,  6,  8,  4,  10,  7,  9]  1  

   HEAP  [2,  3,  4,  5,  6,  8,  9,  10,  7]  2  

   HEAP  [3,  5,  4,  7,  6,  8,  9,  10]  3  

   HEAP  [4,  5,  8,  7,  6,  10,  9]  4  

   HEAP  [5,  6,  8,  7,  9,  10]  5  

   HEAP  [6,  7,  8,  10,  9]  6  

   HEAP  [7,  9,  8,  10]  7  

   HEAP  [8,  9,  10]  8  

   HEAP  [9,  10]  9  

   HEAP  [10]  10  

 

       

build_heap (self,  da:  DynamicArray)  ->  None:   

  

This  method  receives a   dynamic  array  with  objects  in  any  order  and  builds  a  proper  MinHeap  from  them.  Current  content  of  the  MinHeap  is  lost.   

  

Runtime  complexity o f  this  implementation  must  be  O(N). I f  the  runtime  complexity  is  O(NlogN),  you  will  not  receive  any  points  for  this  portion  of  the  assignment,  even  if  you  pass  Gradescope.   

  

Example  #1:  

   da  =  DynamicArray([100,  20,  6,  200,  90,  150,  300])     h  =  MinHeap(['zebra',  'apple'])     print(h)  

   h.build_heap(da)     print(h)  

   da.set_at_index(0,  500)     print(da)     print(h)  

 

  Output:     

   HEAP  ['apple',  'zebra']  

   HEAP  [6,  20,  100,  200,  90,  150,  300]     [500,  20,  6,  200,  90,  150,  300]  

   HEAP  [6,  20,  100,  200,  90,  150,  300]  

 

More products