微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

试图打印出最小堆最后一层的元素

如何解决试图打印出最小堆最后一层的元素

我正在尝试在最小堆中打印最后一个级别。我以为我有有效的代码,但其中一个测试用例失败了。就测试用例而言,我只能访问输出不匹配的方式。

这是我的代码

#include "MinHeap.h"
#include <math.h>

using std::log2;

vector<int> lastLevel(MinHeap & heap)
{
        // Your code here
        vector<int> leaves;
        int capacity = pow(2,log2(heap.elements.size()) + 1) - 1;
        for (unsigned leaf = capacity / 2; leaf < heap.elements.size(); leaf++) {
                leaves.push_back(heap.elements[leaf]);
        }
        return leaves;
}

这是伴随它的 MinHeap 类:

#include "MinHeap.h"

MinHeap::MinHeap(const vector<int> & vector)
{
    int inf = numeric_limits<int>::min();
    elements.push_back(inf);
    elements.insert(elements.end(),vector.begin(),vector.end());
    buildHeap();
}

MinHeap::MinHeap()
{
    int inf = numeric_limits<int>::min();
    elements.push_back(inf);
}

void MinHeap::buildHeap()
{
    std::sort(elements.begin() + 1,elements.end());
}

void MinHeap::heapifyDown(int index)
{
    int length = elements.size();
    int leftChildindex = 2 * index;
    int rightChildindex = 2 * index + 1;

    if (leftChildindex >= length)
        return; // index is a leaf

    int minIndex = index;

    if (elements[index] > elements[leftChildindex]) {
        minIndex = leftChildindex;
    }

    if ((rightChildindex < length)
        && (elements[minIndex] > elements[rightChildindex])) {
        minIndex = rightChildindex;
    }

    if (minIndex != index) {
        // need to swap
        int temp = elements[index];
        elements[index] = elements[minIndex];
        elements[minIndex] = temp;
        heapifyDown(minIndex);
    }
}

void MinHeap::heapifyUp(int index)
{
    if (index < 2)
        return;

    int parentIndex = index / 2;

    if (elements[parentIndex] > elements[index]) {
        int temp = elements[parentIndex];
        elements[parentIndex] = elements[index];
        elements[index] = temp;
        heapifyUp(parentIndex);
    }
}

void MinHeap::insert(int newValue)
{
    int length = elements.size();
    elements.push_back(newValue);
    heapifyUp(length);
}

int MinHeap::peek() const
{
    return elements.at(1);
}

int MinHeap::pop()
{
    int length = elements.size();
    int p = -1;

    if (length > 1) {
        p = elements[1];
        elements[1] = elements[length - 1];
        elements.pop_back();
        heapifyDown(1);
    }

    return p;
}

void MinHeap::print() const
{
    if (elements.size() > 1) {
        int length = elements.size();
        cout << "[";
        for (int i = 1; i < length - 1; i++) {
            cout << elements[i] << ",";
        }
        cout << elements[elements.size() - 1] << "]" << endl;
    } else {
        cout << "[ ]" << endl;
    }
}

这是我得到的输出显示其中一个测试用例失败:

tests.cpp:31: Failed:
  REQUIRE( s_lastLevel(h) == lastLevel(h) )
with expansion:
  { 1804289383 (0x6b8b4567),1681692777 (0x643c9869) }
  ==
  { 1681692777 (0x643c9869) }

===============================================================================
test cases: 1 | 1 Failed
assertions: 3 | 2 passed | 1 Failed

我不确定为什么我最初的方法失败了。非常感谢您的帮助。

解决方法

问题似乎出在这一行:

int capacity = pow(2,log2(heap.elements.size()) + 1) - 1;

你在这里所做的相当于:

int capacity = 2 * heap.elements.size() - 1;

您想要做的是获取最后一个元素的父元素的索引,并将其递增 1 作为迭代的起始位置。由于节点 i 的子节点位于 2i 和 2i+1,因此您可以简单地将最后一个节点 (n-1) 的索引除以 2 并加 1。您可以检查这是否一定是叶子,因为它的子节点位于 2 * ((n-1)/2 + 1)2 * ((n-1)/2 + 1) + 1,它们都保证等于或大于 n。所以这将返回所有叶子:

int start = (heap.elements.size() - 1) / 2 + 1;
for (unsigned leaf = start; leaf < heap.elements.size(); leaf++) {
    leaves.push_back(heap.elements[leaf]);
}
return leaves;

如果只是你想要的最后一层,从小于最后一个元素的索引 (n-1) 的 2 的最大幂开始:

int start = 1 << (int)(log2(heap.elements.size()-1));
for (unsigned leaf = start; leaf < heap.elements.size(); leaf++) {
    leaves.push_back(heap.elements[leaf]);
}
return leaves;

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。