# 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也测试成功了:

treap(堆树)的更多相关文章

  1. K:Treap(堆树)

      Treap=Tree+Heap.Treap是一棵二叉排序树,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是, Treap记录一个额外的数据, 就是优先级.Treap在以关键码构 ...

  2. Treap(树堆)入门

    作者:zifeiy 标签:Treap 首先,我么要知道:Treap=Tree+Heap. 这里: Tree指的是二叉排序树: Heap指的是堆. 所以在阅读这篇文章之前需要大家对 二叉查找树 和 堆( ...

  3. 「模板」「讲解」Treap名次树

    Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...

  4. 查找——图文翔解Treap(树堆)

    之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...

  5. *衡树 Treap(树堆) 学习笔记

    调了好几个月的 Treap 今天终于调通了,特意写篇博客来纪念一下. 0. Treap 的含义及用途 在算法竞赛中很多题目要使用二叉搜索树维护信息.然而毒瘤数据可能让二叉搜索树退化成链,这时就需要让二 ...

  6. Treap(树堆)

    treap是排序二叉树的一种改进,因为排序二叉树有可能会造成链状结构的时候复杂度变成O(n^2)所以通过随机一个优先级的方法来维持每次让优先级最大的作为树根,然后形成一个满足: A. 节点中的key满 ...

  7. Treap(树堆):随机平衡二叉树实现

    本文是根据郭家宝的文章<Treap的原理及实现>写的. #include<stdio.h> #include<string.h> #include<stdli ...

  8. [模板] 平衡树: Splay, 非旋Treap, 替罪羊树

    简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...

  9. Treap——堆和二叉树的完美结合,性价比极值的搜索树

    大家好,今天和大家聊一个新的数据结构,叫做Treap. Treap本质上也是一颗BST(平衡二叉搜索树),和我们之前介绍的SBT是一样的.但是Treap维持平衡的方法和SBT不太一样,有些许区别,相比 ...

随机推荐

  1. 负环--spfa

    洛谷板子题 负环?是有负权边的环还是一个边权之和为负的环? 还没有准确的定义(那就先忽略吧qwq 判断负环的方法: 暴力枚举/spfa/mellman—ford/奇怪的贪心/超神的搜索 可惜我只会sp ...

  2. AT24C02芯片学习记录

    1.首先看AT24C02芯片的引脚说明 2.芯片的型号与存储容量(bit)的对应关系: 3.总线时序 我对时序的理解: 时钟线分两种:一种是外部时钟源控制时钟线低电平持续多久高电平持续多久,就像串口: ...

  3. mybatis批量插入和更新

    批量插入 <insert id="add" parameterType="java.util.List"> insert all <forea ...

  4. 操作word

    package com.gwt.flow.task; import java.io.File; import java.io.FileInputStream; import java.io.FileN ...

  5. localhost: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).

    在开启hadoop时候报错:localhost: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password). 此时 ssh ...

  6. 吴裕雄 python 人工智能——基于Mask_RCNN目标检测(1)

    import os import sys import random import math import numpy as np import skimage.io import matplotli ...

  7. appium常用的类库、对应的方法和属性

    1.driver.swipe(self, start_x, start_y, end_x, end_y, duration=None) tart_x - 滑动开始x轴坐标 start_y - 滑动开始 ...

  8. 数制的运用-CodeForces - 535B

    题解: 因为每一位只可能是4或者7,可以类比二进制的思想. 基数为2,每一位的权值为2i-1:数字4表示的大小为1*2i-1:数字7表示的大小为2*2i-1. 将给定的n按照这种方法进行分解,求和.即 ...

  9. 分享Linux系统快速入门法

    相信看到这篇文章的你一定是想要学习Linux,或者已经在学习Linux的人了,那我们就可以一起探讨一下,学习Linux如何快速入门呢? 首先,希望大家弄清楚自己为什么要学习Linux,有的人是因为兴趣 ...

  10. vscode安装过的插件

    1.VSCode的Vue插件Vetur设置,alt+shift+f格式化 对应配置 今天看到的文章安装插件可以参考: https://blog.csdn.net/maixiaochai/article ...