MinHeap with 2 fields... removeMin and remove given key

newprogrammer :

I have a program to read a list of countries and their GDPs from a file and to insert them into a MinHeap. The heap is a collection(array) of Country objects. A Country object has two fields. A string field called name, which holds the two-letter code of a country and an integer field called gdp, to store the GDP value. The insert method, uses GDP values as keys for insertion. Since this is a MinHeap, the country with minimum GDP is always going to be at the root. Also, all other properties of a heap should be satisfied after each insertion and removal. There won't be any duplicate GDP values in the input file.

I have to complete the Heap.java class to implement the following functions:

removeMinGDP(); should remove the country with minimum GDP from the heap and return it. After removal, the heap property should be restored. return null if the heap was empty.

removeGivenGDP(int gdp): should find the country with the given GDP value and remove it. After removal, the heap property should be restored. This function should return the name of the country that was removed. if a country with the given GDP value can't be found, return an empty string.

I need some help on removeMinGDP. I know I'll be removing the root and replacing it with largest element. I know I have to downheap. I know the general idea but not sure how to perform it. SO BASICALLY I'm stuck because removeMinGDP doesn't accept parameters so I had to create two private methods, BUT I don't what to pass to deleteMin.

I know I haven't started on removeGivenGDP yet (but help will gladly be accepted). And I have very little coding experience so please don't eat me alive.


  private Country[] storage; //the actual heap storing elements
  private int size; //number of elements currently in the heap
  private int cap; //capacity of the heap

  Heap (int c) {
    size = 0;
    cap = c;
    storage = new Country[cap];
  }

  public void insert(Country c) {
    if (size >= cap) {
      throw new IllegalStateException("Heap is full");
    }
    int curr = size++;
    storage[curr] = c;
    while ((curr != 0) && (storage[curr].gdp < storage[parent(curr)].gdp)) {
      exch(storage, curr, parent(curr));
      curr = parent(curr);
    }

  }

  private void exch(Country[] arr, int i, int j) {
    Country tmp = arr[i];
    arr[i] = arr[j];
    arr[j] = tmp;
  }

  private int parent(int i) {
    if (i <= 0) return -1;
    return (i-1)/2;
  }

  public int numCountries () {
    return size;
  }

  public boolean isEmpty() {
    return size == 0;
  }

  private boolean isLeaf(int pos)
  { 
    return (pos >= size/2) && (pos < size); 

  }

  private int leftchild(int pos) {
    if (pos >= size/2) return -1;
    return 2*pos + 1;
  }


  private int rightchild(int pos) {
    if (pos >= (size-1)/2) return -1;
    return 2*pos + 2;
  }

//***************************************************************************

  public Country removeMinGDP() {
    /**************************
     * remove the country with minimum  GDP
     * from the heap and return it. restore
     * the heap properties.
     * return null if heap is empty.
    ***************************/
    if(isEmpty()) return null;
    else{
      return deleteMin(arr,size);
  }
  }

  private Country deleteMin(Country arr[], int n){
    int last = arr[n-1];
    Country temp = arr[0];
    arr[0] = last;
    n = n-1;
    downheap(arr,n,0);
    return temp.name;
  }

  private void downheap(Country arr[], int n, int i){
    int biggest = i;
    int l = 2 * i + 1;
    int r = 2 * i + 2;

    if(l < n && arr[l].gdp > arr[biggest].gdp) biggest = l;
    if(r < n && arr[r].gdp > arr[biggest].gdp) biggest = r;
    if(biggest != i){
      int swap = arr[i];
      arr[i] = arr[biggest];
      arr[biggest] = swap;

      downheap(arr, n, biggest);
    }
  }


  public String removeGivenGDP(int gdp) {
    /**************************
     * TODO: find the country with the given GDP 
     * value and remove it. return the name of 
     * the country and restore the heap property
     * if needed. If no countries with the given GDP
     * were found, return empty string ""
    ***************************/
    return "";
  }
}

Here is the main function.

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

class Main {
  public static void main(String[] args) throws FileNotFoundException {
    File input = new File("countries.txt");

    //Creating Scanner instance to read File
    Scanner sc = new Scanner(input);

    //Create an instance of MinHeap
    Heap h = new Heap(10);

    //Reading each line of file using Scanner class
    while(sc.hasNextLine()){
        String[] tokens = sc.nextLine().split(",");
        System.out.println("Inserted: " + tokens[0] + " -> " + tokens[1]);
        h.insert(new Country(tokens[0], Integer.parseInt(tokens[1].trim())));
    }

    System.out.println("\n\nTotal number of countries inserted is: " + h.numCountries());
    System.out.println("The name of the country with a GDP value of 2314 is " + h.removeGivenGDP(2314));
    System.out.println("Total number of countries now is: " + h.numCountries());

    System.out.println("\n\nCountries in ascending order of GDP values: ");
    while (!h.isEmpty()) {
      Country tmp = h.removeMinGDP();
      System.out.println(tmp.name + " -> " + tmp.gdp);
    } 

  }
}
Jim Mischel :

To remove the given GDP, you have to:

  1. Search the storage array for an entry that contains the requested value.
  2. Copy the last node in the heap to that location.
  3. Reduce the size by 1.
  4. If the new value (the one you copied from the last node) is smaller than its parent, then you need to sift that node up in the heap. Otherwise, you need to sift it down the heap to its proper place.

Yes, that last node certainly can be smaller than the parent of the node you deleted. See https://stackoverflow.com/a/8706363/56778 for an example.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=360667&siteId=1