java - MinHeap 有 2 个字段...removeMin 并删除给定的键

标签 java heap min-heap

我有一个程序可以从文件中读取国家列表及其 GDP,并将它们插入到 MinHeap 中。堆是 Country 对象的集合(数组)。 Country 对象有两个 字段。一个名为 name 的字符串字段,其中包含国家/地区的两个字母代码;以及一个名为 gdp 的整数字段,用于存储 GDP 值。 insert方法,使用GDP值作为插入的键。由于这是一个 MinHeap,GDP 最小的国家始终位于根部。此外,每次插入和删除后都应满足堆的所有其他属性。输入文件中不会有任何重复的 GDP 值。

我必须完成Heap.java类来实现以下功能:

removeMinGDP();应该从堆中删除 GDP 最低的国家并将其返回。删除后,堆属性应恢复。如果堆为空,则返回 null。

removeGivenGDP(int gdp):应找到具有给定 GDP 值的国家并将其删除。删除后,堆属性应恢复。此函数应返回被删除的国家/地区的名称。如果找不到具有给定 GDP 值的国家,则返回空字符串。

我需要一些有关删除MinGDP 的帮助。我知道我将删除根并用最大的元素替换它。我知道我必须下堆。我知道总体思路,但不知道如何执行。所以基本上我被困住了,因为removeMinGDP不接受参数,所以我必须创建两个私有(private)方法,但我不知道要传递给deleteMin什么。

我知道我还没有开始删除GivenGDP(但我们很乐意接受帮助)。而且我的编码经验很少,所以请不要活生生地吃掉我。


  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 "";
  }
}

这是主要功能。

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);
    } 

  }
}

最佳答案

要删除给定的 GDP,您必须:

  1. storage 数组中搜索包含所请求值的条目。
  2. 将堆中的最后一个节点复制到该位置。
  3. 将大小减小 1。
  4. 如果新值(从最后一个节点复制的值)小于其父节点,则需要在堆中向上筛选该节点。否则,您需要将其从堆中筛选到正确的位置。

是的,最后一个节点肯定可以小于您删除的节点的父节点。请参阅https://stackoverflow.com/a/8706363/56778举个例子。

关于java - MinHeap 有 2 个字段...removeMin 并删除给定的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60877235/

相关文章:

c++ - 混淆了堆的两种不同实现

java - 将自定义命名空间定义为从 wsdl - Axis2 eclipse 生成的文件的包映射

java - 'File.delete()' 的结果被忽略

c++ - 如何在不重新建立堆不变量两次的情况下有效地替换堆顶元素?

c++ - C++中最小堆的比较器

c - 近似保序霍夫曼代码

java - Tomcat:显示Web应用程序的维护页面

java - 无法再从 oracle 站点 curl JDK

android - 要在进程中运行dex,Gradle守护程序需要更大的堆。目前大约有1024 MB

algorithm - 优先队列 - 跳过列表与斐波那契堆