treap(堆树)
# 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(堆树)的更多相关文章
- K:Treap(堆树)
Treap=Tree+Heap.Treap是一棵二叉排序树,它的左子树和右子树分别是一个Treap,和一般的二叉排序树不同的是, Treap记录一个额外的数据, 就是优先级.Treap在以关键码构 ...
- Treap(树堆)入门
作者:zifeiy 标签:Treap 首先,我么要知道:Treap=Tree+Heap. 这里: Tree指的是二叉排序树: Heap指的是堆. 所以在阅读这篇文章之前需要大家对 二叉查找树 和 堆( ...
- 「模板」「讲解」Treap名次树
Treap实现名次树 前言 学平衡树的过程可以说是相当艰难.浏览Blog的过程中看到大量指针版平衡树,不擅长指针操作的我已经接近崩溃.于是,我想着一定要写一篇非指针实现的Treap的Blog. 具体如 ...
- 查找——图文翔解Treap(树堆)
之前我们讲到二叉搜索树,从二叉搜索树到2-3树到红黑树到B-树. 二叉搜索树的主要问题就是其结构与数据相关,树的深度可能会非常大,Treap树就是一种解决二叉搜索树可能深度过大的还有一种数据结构. T ...
- *衡树 Treap(树堆) 学习笔记
调了好几个月的 Treap 今天终于调通了,特意写篇博客来纪念一下. 0. Treap 的含义及用途 在算法竞赛中很多题目要使用二叉搜索树维护信息.然而毒瘤数据可能让二叉搜索树退化成链,这时就需要让二 ...
- Treap(树堆)
treap是排序二叉树的一种改进,因为排序二叉树有可能会造成链状结构的时候复杂度变成O(n^2)所以通过随机一个优先级的方法来维持每次让优先级最大的作为树根,然后形成一个满足: A. 节点中的key满 ...
- Treap(树堆):随机平衡二叉树实现
本文是根据郭家宝的文章<Treap的原理及实现>写的. #include<stdio.h> #include<string.h> #include<stdli ...
- [模板] 平衡树: Splay, 非旋Treap, 替罪羊树
简介 二叉搜索树, 可以维护一个集合/序列, 同时维护节点的 \(size\), 因此可以支持 insert(v), delete(v), kth(p,k), rank(v)等操作. 另外, prev ...
- Treap——堆和二叉树的完美结合,性价比极值的搜索树
大家好,今天和大家聊一个新的数据结构,叫做Treap. Treap本质上也是一颗BST(平衡二叉搜索树),和我们之前介绍的SBT是一样的.但是Treap维持平衡的方法和SBT不太一样,有些许区别,相比 ...
随机推荐
- Gitlab+Jenkins用钩子实现git提交后jenkins自动化构建
Gitlab+Jenkins用钩子实现git提交后jenkins自动化构建 一.Jenkins 进入项目---->Configure 1.设置项目代码从git中拉取 2.设置钩子程序 二.git ...
- window下进程退出后自动重启
设计思想:编写批处理脚本监控进程的运行状态,如果发现进程停止,则自动重启该进程.批处理脚本(jk.bat)和进程脚本(hello.bat)如下: 1.jk.bat @echo off rem 定义需监 ...
- if语句的汇编表示
转自:https://blog.csdn.net/u011608357/article/details/22586137 demo: C语言: int max(int x,int y) { if (x ...
- ZooKeeper下载安装配置-单机版配置
1,下载地址:http://apache.fayea.com/zookeeper/ 2,检查环境变量(需要确保配置了环境变量): java -version 3,安装配置: (1)解压 tar -zx ...
- java 生成/解读 二维码
package com.rails.util; import com.swetake.util.Qrcode; import jp.sourceforge.qrcode.QRCodeDecoder; ...
- sockfd_to_family函数
#include <sys/socket.h> #include <netinet/in.h> #define SA struct sockaddr int sockfd_to ...
- mui下拉刷新 ios click事件无法响应问题
使用mui的事件监听事件 tap mui("#pullrefresh").on('tap', '.ulDiv', function (event) {this.click();}) ...
- 获取 python linux Home目录
#! /usr/bin/python # -*- coding: utf-8 -*- import os print os.environ['HOME'] print os.path.expandva ...
- python学习HTML之CSS
1.sytle属性设置 . <head> <meta charset="UTF-8"> <title>Title</title> & ...
- 防止重复发送Ajax请求问题
在工作中有很多场景需要通过Ajax请求发送数据,像是注册.登录.提交用户反馈等.用户在点击了“确认”按钮之后有可能一段时间内没有收到反馈页面无任何反应,然后就接着连续多次点击“确认”按钮导致发送n个重 ...