二叉堆(2)LeftistHeap
左倾堆,用于堆的快速合并。
规则:
① 节点的键值小于或等于它的左右子节点的键值。
② 节点的左孩子的NPL >= 右孩子的NPL。
③ 节点的NPL = 它的右孩子的NPL + 1。
测试文件 main.cpp:
#include <iostream> #include "LeftistHeap.h" using std::cout; using std::endl; int main() { LeftistHeap<int> lh(LeftistHeap<int>::HeapType::MINIMEM); auto il = { ,,,,,,,,, }; for (auto& x : il) lh.push(x); cout << "Element:\n\t"; lh.levelTraversal(); cout << endl << endl; cout << "Pop: " << lh.top() << endl << endl; lh.pop(); cout << "Element:\n\t"; lh.levelTraversal(); cout << endl; ; }
头文件 "LeftistHeap.h":
#pragma once #ifndef __LEFTISTHEAP_H__ #define __LEFTISTHEAP_H__ #include "BinaryTreeOperations.h" template<typename _Ty> class LeftistHeap { struct Node { _Ty key; ; Node* left = nullptr; Node* right = nullptr; Node(const _Ty& _key) :key(_key) {} }; public: , MAXIMEM }; public: LeftistHeap() = default; LeftistHeap(HeapType _heapType) { heapType = _heapType; } ~LeftistHeap() { BTO::clear(root); size_n = ; } ; } void preorderTraversal() { BTO::preorderTraversal(root, drawData); } void inorderTraversal() { BTO::inorderTraversal(root, drawData); } void postorderTraversal() { BTO::postorderTraversal(root, drawData); } void iterativePreorderTraversal() { BTO::iterativePreorderTraversal(root, drawData); } void iterativeInorderTraversal() { BTO::iterativeInorderTraversal(root, drawData); } void iterativePostorderTraversal() { BTO::iterativePostorderTraversal(root, drawData); } void levelTraversal() { BTO::levelTraversal(root, drawData); } size_t size() const { return size_n; } void pop(); _Ty& top() const; void push(const _Ty&); void merge(LeftistHeap<_Ty>&); private: static void drawData(const Node* _node) { std::cout << _node->key << " "; } bool compare(const _Ty& _a, const _Ty& _b) { return (heapType == HeapType::MAXIMEM) ? (_a > _b) : (_a < _b); } Node* merge(Node*&, Node*&); private: Node* root = nullptr; size_t size_n = ; HeapType heapType = HeapType::MAXIMEM; }; template<typename _Ty> void LeftistHeap<_Ty>::pop() { if (root == nullptr) throw std::exception("LeftistHeap is empty!"); Node* leftT = root->left; Node* rightT = root->right; delete root; root = merge(leftT, rightT); --size_n; } template<typename _Ty> _Ty& LeftistHeap<_Ty>::top() const { if (root == nullptr) throw std::exception("LeftistHeap is empty!"); return root->key; } template<typename _Ty> void LeftistHeap<_Ty>::push(const _Ty& _key) { Node* temp = new Node(_key); root = merge(root, temp); temp = nullptr; ++size_n; } template<typename _Ty> void LeftistHeap<_Ty>::merge(LeftistHeap<_Ty>& _lh) { if (heapType != _lh.heapType) throw std::exception("Bad heapType"); root = merge(root, _lh.root); _lh.root = nullptr; size_n += _lh.size_n; _lh.size_n = ; } template<typename _Ty> typename LeftistHeap<_Ty>::Node* LeftistHeap<_Ty>::merge(Node*& _n1, Node*& _n2) { if (_n1 == nullptr && _n2 == nullptr) return nullptr; else if (_n1 == nullptr) return _n2; else if (_n2 == nullptr) return _n1; if (!compare(_n1->key, _n2->key)) std::swap(_n1, _n2); _n1->right = merge(_n1->right, _n2); if (_n1->left == nullptr || _n1->left->NPL < _n1->right->NPL) std::swap(_n1->left, _n1->right); ; ; return _n1; } #endif // !__LEFTISTHEAP_H__
二叉堆(2)LeftistHeap的更多相关文章
- AC日记——二叉堆练习3 codevs 3110
3110 二叉堆练习3 时间限制: 3 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 给定N(N≤500,000)和N个整 ...
- codevs 3110 二叉堆练习3
3110 二叉堆练习3 http://codevs.cn/problem/3110/ 题目描述 Description 给定N(N≤500,000)和N个整数(较有序),将其排序后输出. 输入描述 I ...
- 数据结构图文解析之:二叉堆详解及C++模板实现
0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...
- POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆
考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...
- 二叉堆(一)之 图文解析 和 C语言的实现
概要 本章介绍二叉堆,二叉堆就是通常我们所说的数据结构中"堆"中的一种.和以往一样,本文会先对二叉堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本 ...
- 二叉堆(二)之 C++的实现
概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...
- 二叉堆(三)之 Java的实现
概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的Java实现(完整源码) ...
- 二叉堆(binary heap)
堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因 ...
- 在A*寻路中使用二叉堆
接上篇:A*寻路初探 GameDev.net 在A*寻路中使用二叉堆 作者:Patrick Lester(2003年4月11日更新) 译者:Panic 2005年3月28日 译者序 这一篇文章,是&q ...
- 《Algorithms算法》笔记:优先队列(2)——二叉堆
二叉堆 1 二叉堆的定义 堆是一个完全二叉树结构(除了最底下一层,其他层全是完全平衡的),如果每个结点都大于它的两个孩子,那么这个堆是有序的. 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组 ...
随机推荐
- SELinux 和 iptables 开启关闭
SELinux 是 2.6 版本的 Linux 内核中提供的强制访问控制(MAC)系统.对于目前可用的 Linux安全模块来说,SELinux 是功能最全面,而且测试最充分的,它是在 20 年的 MA ...
- linux系统的启动流程梳理
1. 不同版本的linux系统的启动流程 1.1 centos6.x系统的启动流程 其详细启动步骤如下: 1)开机,BIOS自检,检查各个硬件是否正常 2)读取硬盘MBR信息,引导系统启动 3)加载g ...
- oracle11g R2数据库的迁移(同windows系统迁移)使用RMAN
实验环境:windows 2008 R2 & windows 2008 R2 Oracle版本:11.2.0.1.0 源数据库端: 为保证在恢复之后的数据库中得到一致的数据,应禁止用户对数据的 ...
- Linux运维-磁盘存储---3.LVM
LVM的工作原理 LVM( Logical Volume Manager)逻辑卷管理,是在磁盘分区和文件系统之间添加的一个逻辑层,来为文件系统屏蔽下层磁盘分区布局,提供一个抽象的盘卷,在盘卷上建立文件 ...
- [WPF 学习] 3.用户控件库使用资源字典的困惑
项目需要(或者前后端分离的需要),前端我使用了用户控件库,由后端用代码加载和控制. 然而用户控件库没法指定资源字典,于是在用户控件的xaml文件里面手工添加了资源字典 <UserControl. ...
- C#中WinFrom保存文件SaveFileDialog类的使用方法
C#中WinFrom保存文件SaveFileDialog类的使用方法 使用的命名空间是:System.Windows.Forms; 常用属性: Title:保存对话框的标题,默认为"另存 ...
- 在pycharm中如何设置代码对齐竖线
方法:启动pycharm软件,打开一个文件,点 file 菜单,选择 settings,在弹出的setting菜单中依次选择editor-->general-->appearance,然后 ...
- 浅谈 vue-loader---合格前端
什么是 vue-loader? vue-loader 是一个 webpack 的 loader,它允许你以一种名为单文件组件的格式撰写 Vue 组件. 如何使用? 1. 安装 npm install ...
- AI Web 1.0
kali:192.168.0.103 目标机:192.168.0.105 0X01 端口和目录扫描 打开目标主页没有任何信息 a) 端口扫描 只有一个80端口开启 b) 目录扫描 0x03 查看敏感目 ...
- 解决 Windows 编译 Fast R-CNN 的 bbox 和 nms 出现的错误 error: Unable to find vcvarsall.bat
在 Windows 下安装一个底层的 Python 包时(Fast R-CNN 的 bbox 和 nms),遇到 error: Unable to find vcvarsall.bat 错误,看到这个 ...