构建堆的算法
Algorithm that builds heap
我正在尝试实现创建堆的build_max_heap
函数(因为它是在Cormen的"介绍做算法"中编写的)。但是我得到奇怪的错误,我不能定位它。我的程序成功地给随机数表,显示它们,但在build_max_heap()
之后,我得到了奇怪的数字,这可能是因为我的程序在某个地方达到了表外的东西,但我找不到这个错误。我将很高兴得到任何帮助。
例如,我得到表:
0 13 18 0 22 15 24 19 5 23
我的输出是:
24 7 5844920 5 22 15 18 19 0 23
我代码:#include <iostream>
#include <ctime>
#include <stdlib.h>
const int n = 12; // the length of my table, i will onyl use indexes 1...n-1
struct heap
{
int *tab;
int heap_size;
};
void complete_with_random(heap &heap2)
{
srand(time(NULL));
for (int i = 1; i <= heap2.heap_size; i++)
{
heap2.tab[i] = rand() % 25;
}
heap2.tab[0] = 0;
}
void show(heap &heap2)
{
for (int i = 1; i < heap2.heap_size; i++)
{
std::cout << heap2.tab[i] << " ";
}
}
int parent(int i)
{
return i / 2;
}
int left(int i)
{
return 2 * i;
}
int right(int i)
{
return 2 * i + 1;
}
void max_heapify(heap &heap2, int i)
{
if (i >= heap2.heap_size || i == 0)
{
return;
}
int l = left(i);
int r = right(i);
int largest;
if (l <= heap2.heap_size || heap2.tab[l] > heap2.tab[i])
{
largest = l;
}
else
{
largest = i;
}
if (r <= heap2.heap_size || heap2.tab[r] > heap2.tab[i])
{
largest = r;
}
if (largest != i)
{
std::swap(heap2.tab[i], heap2.tab[largest]);
max_heapify(heap2, largest);
}
}
void build_max_heap(heap &heap2)
{
for (int i = heap2.heap_size / 2; i >= 1; i--)
{
max_heapify(heap2, i);
}
}
int main()
{
heap heap1;
heap1.tab = new int[n];
heap1.heap_size = n - 1;
complete_with_random(heap1);
show(heap1);
std::cout << std::endl;
build_max_heap(heap1);
show(heap1);
}
实际上,该表是通过越界索引访问的。
if (l <= heap2.heap_size || heap2.tab[l] > heap2.tab[i])
^^
我想你在这种情况下指的是&&
。
下一个r
分支相同。
如果您仍然有问题,下面是我自己的实现,您可以使用作为参考。它也是基于Cormen等人的书,所以它使用了或多或少相同的术语。它可以为实际容器、比较函数和交换函数提供任意类型。它提供了一个公共的类似队列的接口,包括键递增。
因为它是一个更大的软件集合的一部分,它使用了一些这里没有定义的实体,但我希望算法仍然清晰。CHECK
只是一个断言机制,您可以忽略它。你也可以忽略swap
成员,只使用std::swap
。
代码的某些部分使用基于1的偏移量,其他部分使用基于0的偏移量,因此需要进行转换。每个方法上面的注释都表明了这一点。
template <
typename T,
typename ARRAY = array <T>,
typename COMP = fun::lt,
typename SWAP = fun::swap
>
class binary_heap_base
{
protected:
ARRAY a;
size_t heap_size;
SWAP swap_def;
SWAP* swap;
// 1-based
size_t parent(const size_t n) { return n / 2; }
size_t left (const size_t n) { return n * 2; }
size_t right (const size_t n) { return n * 2 + 1; }
// 1-based
void heapify(const size_t n = 1)
{
T& x = a[n - 1];
size_t l = left(n);
size_t r = right(n);
size_t select =
(l <= heap_size && COMP()(x, a[l - 1])) ?
l : n;
if (r <= heap_size && COMP()(a[select - 1], a[r - 1]))
select = r;
if (select != n)
{
(*swap)(x, a[select - 1]);
heapify(select);
}
}
// 1-based
void build()
{
heap_size = a.length();
for (size_t n = heap_size / 2; n > 0; n--)
heapify(n);
}
// 1-based
size_t advance(const size_t k)
{
size_t n = k;
while (n > 1)
{
size_t pn = parent(n);
T& p = a[pn - 1];
T& x = a[n - 1];
if (!COMP()(p, x)) break;
(*swap)(p, x);
n = pn;
}
return n;
}
public:
binary_heap_base() { init(); set_swap(); }
binary_heap_base(SWAP& s) { init(); set_swap(s); }
binary_heap_base(const ARRAY& a) { init(a); set_swap(); }
binary_heap_base(const ARRAY& a, SWAP& s) { init(a); set_swap(s); }
void init() { a.init(); build(); }
void init(const ARRAY& a) { this->a = a; build(); }
void set_swap() { swap = &swap_def; }
void set_swap(SWAP& s) { swap = &s; }
bool empty() { return heap_size == 0; }
size_t size() { return heap_size; }
size_t length() { return heap_size; }
void reserve(const size_t len) { a.reserve(len); }
const T& top()
{
CHECK (heap_size != 0, eshape());
return a[0];
}
T pop()
{
CHECK (heap_size != 0, eshape());
T x = a[0];
(*swap)(a[0], a[heap_size - 1]);
heap_size--;
heapify();
return x;
}
// 0-based
size_t up(size_t n, const T& x)
{
CHECK (n < heap_size, erange());
CHECK (!COMP()(x, a[n]), ecomp());
a[n] = x;
return advance(n + 1) - 1;
}
// 0-based
size_t push(const T& x)
{
if (heap_size == a.length())
a.push_back(x);
else
a[heap_size] = x;
return advance(++heap_size) - 1;
}
};
相关文章:
- C++为构建时间获取QDateTime的可靠方法
- 无法在 CLion 中构建 C++ 项目
- 函数向量_指针有不同的原型,我可以构建一个吗
- 如何使用ndk-build.cmd构建Android.so文件
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- libssh 的函数在构建 libssh 时无法在 Qt 和 cmake 错误中找到
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 使用cmake从源代码构建MySQL连接器/C++失败(与以前的声明冲突)
- VSCode-有一个红色下划线,但程序构建和运行正确,并且出现配音错误
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 构建JSON对象的算法
- 如何在 C 或 C++ 中实现 3d kDTree 构建和搜索算法
- 在当前给定的通用场景中,我如何正确地为Hopcroft-Carp最大匹配算法构建图
- 构建最大堆算法不起作用
- 构建堆的算法