通过 insertKey 和 buildHeap 构建堆获得不同的答案

Posted

技术标签:

【中文标题】通过 insertKey 和 buildHeap 构建堆获得不同的答案【英文标题】:Getting different answers by building heap one by insertKey and other by buildHeap 【发布时间】:2017-11-29 04:48:06 【问题描述】:

我只是尝试构建一个最小堆,但我得到了构建堆的不同答案

方法 1 将元素插入数组,然后调用构建 minheap 方法,该方法将 minHeapify 应用于内部节点。

方法 2 通过检查数组是否遵循 minheap 属性,将元素直接插入堆中。

我猜两个答案都是正确的,但是如果某些测试用例显示一个订单并且答案不同,那可以吗?

#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int leftChild(int i)

    return (2*i+1);

int rightChild(int i)

    return (2*i+2);

int parent(int i)

    return ((i-1)/2);

void minHeapify(vector<int> &a,int i)

    int smallest = i;
    int l = leftChild(i);
    int r = rightChild(i);
    if(l < a.size() && a[l] < a[i])
        smallest = l;
    if(r < a.size() && a[r] < a[smallest])
        smallest = r;
    if(smallest != i)
    
        swap(a[smallest],a[i]);
        minHeapify(a,smallest);
    

void buildMinHeap(vector<int> &a)

    for(int i = a.size()/2 - 1 ; i >= 0 ; i--)
        minHeapify(a,i);

void insertKey(vector<int> &b,int new_val,int* n)

    *n = *n + 1;
    int i = *n - 1;
    b[i] = new_val;
    while(i!=0 && b[i] < b[parent(i)])
    
        swap(b[i],b[parent(i)]);
        i = parent(i);
    

void printline()

    cout<<"********************************************************************"<<endl;

int main()

    cout<<"Enter the elements in the array for building a min heap"<<endl;
    vector<int> a;
    a.push_back(2);
    a.push_back(16);
    a.push_back(74);
    a.push_back(58);
    a.push_back(36);
    a.push_back(4);
    a.push_back(28);
    a.push_back(15);
    a.push_back(35);
    a.push_back(82);
    a.push_back(6);

    //One thing you can do is make a normal array and build a heap out of it in O(n) time
    buildMinHeap(a);
    for(int i=0;i<a.size();i++)
        cout<<a[i]<<" ";
    cout<<endl<<endl;
    printline();

    //Or second method is insert in a way such that it is always inserted in a form of heap.
    vector<int> b(10000);
    int heapsize = 0;
    insertKey(b,2,&heapsize);
    insertKey(b,16,&heapsize);
    insertKey(b,74,&heapsize);
    insertKey(b,58,&heapsize);
    insertKey(b,36,&heapsize);
    insertKey(b,4,&heapsize);
    insertKey(b,28,&heapsize);
    insertKey(b,15,&heapsize);
    insertKey(b,35,&heapsize);
    insertKey(b,82,&heapsize);
    insertKey(b,6,&heapsize);
    for(int i=0;i<heapsize;i++)
        cout<<b[i]<<" ";

我使用 min_heap 函数进行了检查,并根据我的两个答案构建了一个最小堆。 min_heap(a.begin(),a.end(),myComparator()) 产生与方法 1 相同的 ans 和 min_heap(b.begin(),b.end(),myComparator()) 产生相同的 ans 产生通过方法2。所以我只是想确认一下这件事好吗???

【问题讨论】:

在编码竞赛中,如果测试用例有预定义的输出,我怎么知道要使用哪种方法? 【参考方案1】:

对于堆,保存在底层数据结构中的元素顺序并不重要。

您应该检查最小堆中弹出的值是否按升序排列,即根元素始终是最小值。

top()pop() 方法添加到您的两个结构中。 top() 将简单地返回根元素值,pop() 将删除根元素并用堆中合适的元素替换它。

以下代码应该以相同的顺序打印元素。

while(heap.size() > 0)

std::cout<<heap.top()<<" ";
heap.pop();

对于编码比赛,他们永远不会检查底层结构的顺序。您应该按顺序打印它们。

【讨论】:

以上是关于通过 insertKey 和 buildHeap 构建堆获得不同的答案的主要内容,如果未能解决你的问题,请参考以下文章

当我尝试在 Visual Studio 中输入时,它会覆盖下一个字符 [重复]

visualstudio输入前面的字后面会删除

堆排序

python实现优先队列

实现优先级队列(小根堆)

插入并堆排序到用数组构建的堆