二进制最小堆:打印未存储的值

Binary Min Heap : Printing unstored values

本文关键字:存储 打印 二进制      更新时间:2023-10-16

我有一个二进制堆的实现是这样的:
我必须找出代码末尾显示错误输出的原因。

我还需要删除myminheap对象打印后,它是弹出元素一个接一个!

heap.h

#include <cstdlib>
#include <vector>
#include <iterator>
using namespace std;
class Heap
{
  public:
    Heap() {}
    ~Heap() {}
    vector <int> heap;
    int left(int parent);
    int right(int parent);
    int parent(int child);
    int size()                  {return heap.size();}
    void print();
};
class MinHeap : public Heap
{
  private:
    void heapify_up(int index);
    void heapify_down(int index);
  public:
    MinHeap() {}
    ~MinHeap() {}
    int pop_min();
    void insert(int element);
};
class MaxHeap : public Heap
{
  private:
    void heapify_up(int index);
    void heapify_down(int index);
  public:
    MaxHeap() {}
    ~MaxHeap() {}
    int pop_max();
    void insert(int element);
};

heap.cc

#include <cstdlib>
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
#include "heap.h"
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int Heap::left(int parent)
{
    int i = (parent << 1) + 1;  //2 * parent + 1    read more on bit shifts
    return (i < heap.size()) ? i : -1;
}
int Heap::right(int parent)
{
    int i = (parent << 1) + 2;
    return (i < heap.size()) ? i : -1;
}
int Heap::parent(int child)
{
    if(child){
        int i = (child >> 1) - 1;
        return i;
    }
    else return -1;
}
void Heap::print()
{
    vector<int>::iterator i = heap.begin();
    cout << "Heap = ";
    while(i != heap.end()){
        cout << *i << " ";
        i++;
    }
    cout << endl;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MinHeap::pop_min()
{
    int min = heap.front();
    heap[0] = heap[heap.size() - 1];
    heap.pop_back();
    heapify_down(0);
    return min;
}
void MinHeap::insert(int element)
{
    heap.push_back(element);
    heapify_up(heap.size() - 1);
}
void MinHeap::heapify_up(int index)
{
    while(index > 0 && parent(index) >= 0 && heap[parent(index)] > heap[index]){
        int temp = heap[index];
        heap[index] = heap[parent(index)];
        heap[parent(index)] = temp;
        index = parent(index);
    }
}
void MinHeap::heapify_down(int index)
{
    int child = left(index);
    if(child > 0 && right(index) > 0 && heap[child] > heap[right(index)])
        child = right(index);
    if(heap[index] > heap[child]){
        int temp = heap[child];
        heap[child] = heap[index];
        heap[index] = temp;
        heapify_down(child);
    }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int MaxHeap::pop_max()
{
    int max = heap.front();
    heap[0] = heap[heap.size() - 1];
    heap.pop_back();
    heapify_down(0);
    return max;
}
void MaxHeap::insert(int element)
{
    heap.push_back(element);
    heapify_up(heap.size() - 1);
}
void MaxHeap::heapify_up(int index)
{
    while(index > 0 && parent(index) >= 0 && heap[parent(index)] < heap[index]){
        int temp = heap[index];
        heap[index] = heap[parent(index)];
        heap[parent(index)] = temp;
        index = parent(index);
    }
}
void MaxHeap::heapify_down(int index)
{
    int child = left(index);
    if(child > 0 && right(index) > 0 && child < right(index))
        child = right(index);
    if(heap[index] < heap[child]){
        int temp = heap[child];
        heap[child] = heap[index];
        heap[child] = temp;
        heapify_down(child);
    }
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//              test program
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main(){
    // Create the heap
    MinHeap* myminheap = new MinHeap();
    myminheap->insert(700);
    myminheap->print();
    myminheap->insert(500);
    myminheap->print();
    myminheap->insert(100);
    myminheap->print();
    myminheap->insert(800);
    myminheap->print();
    myminheap->insert(200);
    myminheap->print();
    myminheap->insert(400);
    myminheap->print();
    myminheap->insert(900);
    myminheap->print();
    myminheap->insert(1000);
    myminheap->print();
    myminheap->insert(300);
    myminheap->print();
    myminheap->insert(600);
    myminheap->print();
    // Get priority element from the heap
    int heapSize = myminheap->size();
    for ( int i = 0; i < heapSize; i++ )
        cout << "Get min element = " << myminheap->pop_min() << endl;
    return 1;
}

这会产生如下所示的乱码输出:

Heap = 700 
Heap = 700 500 
Heap = 100 500 700 
Heap = 100 500 700 800 
Heap = 100 200 700 800 500 
Heap = 100 200 700 800 500 400 
Heap = 100 200 700 800 500 400 900 
Heap = 100 200 700 800 500 400 900 1000 
Heap = 100 200 700 300 500 400 900 1000 800 
Heap = 100 200 700 300 500 400 900 1000 800 600 
Get min element = 100
Get min element = 200
Get min element = 300
Get min element = 500
Get min element = 73
Get min element = 400
Get min element = 600
Get min element = 700
Get min element = 800
Get min element = 900

两个bug;下面的代码修复了它们(并且我已经将位移位更改回mult/div -这没有区别。当自然表达式是mult/div除以2时,为什么要使用移位?如果你在考虑优化,那么。bug是什么,我把它作为练习....

// Num 1
int Heap::parent(int child)
{
    if(child > 0){
        int i = (child / 2);
        return i;
    }
    else return -1;
}
// Num 2
void MinHeap::heapify_down(int index)
{
    int child = left(index);
    if(child > 0 && right(index) > 0 && heap[child] > heap[right(index)])
        child = right(index);
    if(child > 0 && heap[index] > heap[child]){
        int temp = heap[child];
        heap[child] = heap[index];
        heap[index] = temp;
        heapify_down(child);
    }
}

你必须删除myminheap。逐个弹出元素并不意味着当容器中的元素计数达到0时容器会自动销毁。