# 2018-09-27 17:35:58 我实现的这个treap不能算是堆。有问题
最近对堆这种结构有点感兴趣,然后想用指针的方式实现一个堆而不是利用数组这种结构,于是自己想到了一个用二叉树结构实现堆的算法,下面是主要操作的源码:
头文件:
#ifndef _HEAP_H__
#define _HEAP_H__
#include <iostream>
#include <vector>
template<class type>
class BaseNode {
private:
type val;
BaseNode *left, *right;
public:
BaseNode() {}
BaseNode(type v) : val(v), left(nullptr), right(nullptr) {}
/**/
void value(type val) { this->val = val; }
void lchild(BaseNode *left) { this->left = left; }
void rchild(BaseNode *right) { this->right = right; }
type value() { return val; }
BaseNode* lchild() { return left; }
BaseNode* rchild() { return right; }
};
template<class type>
class treap : protected BaseNode<type> {
BaseNode<type> *root;
size_t count;
public:
treap() : root(nullptr), count(0) {}
treap(std::vector<type> iter_type_vec) {
for (int i = 0; i < iter_type_vec.size(); i++)
insert(iter_type_vec[i]);
}
~treap() {
delete root;
}
bool empty() const {
if (count == 0)
return true;
return false;
}
size_t size() const {
return count;
}
type top() const {
if (empty())
{
std::cout << "Underflow!" << std::endl;
return -1;
}
return root->value();
}
void show() const {
travel(root);
std::cout << std::endl;
};
void insert(type val);
void remove();
void travel(BaseNode<type> *pr) const;
};
#endif // _HEAP_H__
定义函数的实现:
#include "Heap.h"
template<class type>
void treap<type>::insert(type val)
{
BaseNode<type> *node = new BaseNode<type>(val);
if (!root)
root = node;
else if (root->value() <= val)
{
node->lchild(root);
root = node;
}
else
{
if (root->lchild() && root->rchild()) {
BaseNode<type> *pr = root;
while (pr) {
if (pr->lchild() && pr->lchild()->value() > val)
pr = pr->lchild();
else if (pr->rchild() && pr->rchild()->value() > val)
pr = pr->rchild();
else
break;
}
if (!pr->lchild())
pr->lchild(node);
else if (!pr->rchild())
pr->rchild(node);
else {
BaseNode<type> *tem = pr->lchild();
pr->lchild(node);
node->lchild(tem);
}
}
else if (!root->lchild())
root->lchild(node);
else
root->rchild(node);
}
++count;
}
template<class type>
void treap<type>::remove()
{
if (!empty())
{
if (root->lchild() && root->rchild())
{
if (root->lchild()->value() > root->rchild()->value())
{
BaseNode<type> *rr = root->rchild();
root = root->lchild();
BaseNode<type> *tem = root->rchild();
if (!tem)
root->rchild(rr);
else {
BaseNode<type> *pr = root->rchild();
while (pr) {
if (pr->lchild() && pr->lchild()->value() > rr->value())
pr = pr->lchild();
else if (pr->rchild() && pr->rchild()->value() > rr->value())
pr = pr->rchild();
else
break;
}
if (!pr->lchild())
pr->lchild(rr);
else
pr->lchild(rr);
}
}
else {
BaseNode<type> *rr = root->lchild();
root = root->rchild();
BaseNode<type> *tem = root->lchild();
if (!tem)
root->lchild(rr);
else {
BaseNode<type> *pr = root->lchild();
while (pr) {
if (pr->lchild() && pr->lchild()->value() > rr->value())
pr = pr->lchild();
else if (pr->rchild() && pr->rchild()->value() > rr->value())
pr = pr->rchild();
else
break;
}
if (!pr->lchild())
pr->lchild(rr);
else
pr->rchild(rr);
}
}
}
else if (root->lchild())
root = root->lchild();
else
root = root->rchild();
--count;
}
}
template<class type>
void treap<type>::travel(BaseNode<type> *pr) const
{
if (pr) {
std::cout << pr->value() << ' ';
travel(pr->lchild());
travel(pr->rchild());
}
}
测试:
#include <iostream>
#include <vector>
#include "Heap.cpp"
int main()
{
std::vector<int> nums{1,5,3,2,4};
treap<int> trees;
for (auto v : nums)
trees.insert(v);
std::cout << "当前堆节点个数:" << trees.size() << std::endl;
std::cout << "遍历堆树:";
trees.show();
std::cout << std::endl;
while (!trees.empty()) {
std::cout << "当前堆顶数据:" << trees.top() << std::endl;
trees.remove();
}
return 0;
}
运行结果:

在Windows上VS和CodeBlocks上都测试成功了,VS上是代码都在一个文件中测试的,codeblocks上不知道为什么必须用 #include "Heap.cpp" 而不能用 #include "Heap.h",否则会报错。。。
CentOS7 gcc 8.1.0也测试成功了:
