如何为最小堆编写添加函数?

Posted

技术标签:

【中文标题】如何为最小堆编写添加函数?【英文标题】:How does one write an add function for a min heap? 【发布时间】:2021-09-29 05:13:31 【问题描述】:

我正在尝试为 Java 中的最小堆编写一个添加函数,但我似乎无法编写一个正常工作的函数。我已经为 add 方法尝试了两种解决方案,但似乎都不起作用。我尝试使用 int 来存储先前的位置,然后将其重新插入堆中,但这不会产生任何结果。任何帮助将不胜感激。

public class ClsPQHeap 
    private int back;
    private int heap[];

public ClsPQHeap (int amount)
    heap = new int[amount];
    back = 0;

public boolean isEmpty()
    if (back == 0)
      return true;  
     else 
      return false;  
    

public boolean isFull()
    if (heap.length == back)
        return true;
     else 
        return false;
    

// this is the method that needs help 
public void add(int x)
    if (isEmpty()) 
        heap[back] = x;
     else if (isFull())
      System.out.println("Did not add " + x + " array is full");
    else 
        heap[back + 1] = x;
        for (int i = heap.length; i <= back; i--)
            if (heap[i] > heap[i-1])
                int temp = heap[i];
                heap[i] = heap[i-1];
                heap[i-1] = temp;
             else if (heap[i] < heap[i -1])
                int temp = heap[i];
            
        
        /*do 
            if (heap[back] > heap[back+1])
                int temp = heap[back];
                heap[back] = heap[back + 1];
                heap[back + 1] = temp;
             else if (heap[back] < heap[back+1])
            
            
         while (heap[0] > heap[back]); */
        back += 1;    
     

public void print()
  int count = 1;
  for(int i = 0; i<back; i++)
     System.out.println(count + "." + heap[i]);
     count += 1;
  

public static void main(String[] args) 
    
    int myArray[] = 15, 5, 8, 4, 9, 22, 17, 2, 14, 1;
    ClsPQHeap heap = new ClsPQHeap(myArray.length);
    for(int i = 0; i<myArray.length; i++)
        heap.add(myArray[i]);
        heap.print();
        System.out.println("");
    


自从我将它发布到添加功能后,我已经取得了一些进展。我现在可以打印其中的一些,但这些值没有被正确打印或正确添加。这是我目前所在的位置:

public void add(int x)
    back = back+1;
    if (isEmpty()) 
        heap[back] = x;
     else if (isFull())
      System.out.println("Did not add " + x + " array is full");
      back = back-1;
    
    heap[back + 1] = x;
    for (int i = 1; i<= back+1; i++)
        if (heap[i-1] <= heap[(i-1)/2])
            int holder;
            holder = heap[i-1];
            heap[i-1] = heap[(i-1)/2];
            heap[(i-1)/2] = holder; 
            
        

【问题讨论】:

【参考方案1】:

一些问题:

for 条件在第一个版本中是错误的:当您减少 i 时,条件应该违反最小限制,例如i &gt;= 0。在第二个版本中,它是一个递增循环,解决了这个问题,只是插入算法确实需要一个递减循环——表示从树的底部到根的遍历。

在第一个版本中,当列表为空时,您不会增加 back。这在第二个版本中得到解决。但是,在第二个版本中,您不会填充索引 0 处的条目。

在第一个版本中,子节点和父节点之间的关系不是根据索引计算的。这在第二个版本中得到了更好的体现——使用除以 2——但它仍然不完全正确。

这是如何做到的。请注意,无需区别对待空列表。此外,无需在每次迭代中交换。只需将值向下移动,为值x 留出空隙,但仅在确定 目标索引时才分配值x。这样可以节省一些不必要的任务。

    public void add(int x)
        if (isFull())
            System.out.println("Did not add " + x + " array is full");
         else 
            int child = back;
            int parent = (child - 1) / 2;
            while (child > 0 && heap[parent] > x) 
                heap[child] = heap[parent];
                child = parent;
                parent = (child - 1) / 2;
            
            heap[child] = x;
            back++;
        
    

【讨论】:

@Megan,您的编辑建议不正确。但是,您能留下一些反馈吗?这回答了你的问题吗?

以上是关于如何为最小堆编写添加函数?的主要内容,如果未能解决你的问题,请参考以下文章

最小函数值(堆)

在删除 c ++ 时维护最小堆

priorityQueue 堆

P2085 最小函数值 (堆)

P2085 最小函数值 堆

最小堆排序MinHeap