左倾堆,用于堆的快速合并。

规则:

    ① 节点的键值小于或等于它的左右子节点的键值。

    ② 节点的左孩子的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的更多相关文章

  1. AC日记——二叉堆练习3 codevs 3110

    3110 二叉堆练习3  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 给定N(N≤500,000)和N个整 ...

  2. codevs 3110 二叉堆练习3

    3110 二叉堆练习3 http://codevs.cn/problem/3110/ 题目描述 Description 给定N(N≤500,000)和N个整数(较有序),将其排序后输出. 输入描述 I ...

  3. 数据结构图文解析之:二叉堆详解及C++模板实现

    0. 数据结构图文解析系列 数据结构系列文章 数据结构图文解析之:数组.单链表.双链表介绍及C++模板实现 数据结构图文解析之:栈的简介及C++模板实现 数据结构图文解析之:队列详解与C++模板实现 ...

  4. POJ 2010 - Moo University - Financial Aid 初探数据结构 二叉堆

    考虑到数据结构短板严重,从计算几何换换口味= = 二叉堆 简介 堆总保持每个节点小于(大于)父亲节点.这样的堆被称作大根堆(小根堆). 顾名思义,大根堆的数根是堆内的最大元素. 堆的意义在于能快速O( ...

  5. 二叉堆(一)之 图文解析 和 C语言的实现

    概要 本章介绍二叉堆,二叉堆就是通常我们所说的数据结构中"堆"中的一种.和以往一样,本文会先对二叉堆的理论知识进行简单介绍,然后给出C语言的实现.后续再分别给出C++和Java版本 ...

  6. 二叉堆(二)之 C++的实现

    概要 上一章介绍了堆和二叉堆的基本概念,并通过C语言实现了二叉堆.本章是二叉堆的C++实现. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的C++实现(完整源码)4. 二叉堆的C++测试程 ...

  7. 二叉堆(三)之 Java的实现

    概要 前面分别通过C和C++实现了二叉堆,本章给出二叉堆的Java版本.还是那句话,它们的原理一样,择其一了解即可. 目录1. 二叉堆的介绍2. 二叉堆的图文解析3. 二叉堆的Java实现(完整源码) ...

  8. 二叉堆(binary heap)

    堆(heap) 亦被称为:优先队列(priority queue),是计算机科学中一类特殊的数据结构的统称.堆通常是一个可以被看做一棵树的数组对象.在队列中,调度程序反复提取队列中第一个作业并运行,因 ...

  9. 在A*寻路中使用二叉堆

    接上篇:A*寻路初探 GameDev.net 在A*寻路中使用二叉堆 作者:Patrick Lester(2003年4月11日更新) 译者:Panic 2005年3月28日 译者序 这一篇文章,是&q ...

  10. 《Algorithms算法》笔记:优先队列(2)——二叉堆

    二叉堆 1 二叉堆的定义 堆是一个完全二叉树结构(除了最底下一层,其他层全是完全平衡的),如果每个结点都大于它的两个孩子,那么这个堆是有序的. 二叉堆是一组能够用堆有序的完全二叉树排序的元素,并在数组 ...

随机推荐

  1. Firewall 防火墙

    firewalld和iptables的关系: firewalld自身并不具备防火墙的功能,而是和iptables一样需要通过内核的netfilter来实现.也就是说firewalld和iptables ...

  2. php 的file 缓存

    PDO方式连接数据库类 <?php /** * @author 黄功延 * createTime 2018/5/28 0028 09:44 */ class Db { //私有化数据库连接数据, ...

  3. [Contract] Solidity address payable 转换与数组地址

    address payable  -->  address address payable addr1 = msg.sender; address addr2 = addr1; // 隐式转 a ...

  4. linux中vim使用技巧

    一.导入文件内容 :r 解释 导入文件 示例 编辑模式下 # 将/tmp/test.txt内容导入到光标所在的位置的下一行 :r /tmp/test.txt :! 解释 在编辑文件时,执行系统命令 示 ...

  5. 11种常用css样式之border学习

    边框border通常简写为"border:1px solid red;"但其实一个完整的border边框其实是由1.border-width/*边框宽度*/,2.border-st ...

  6. springboot~HttpPut开启application/x-www-form-urlencoded

    在使用spring框架时,默认情况下@RequestParam注解只到接受Get和Post请求参数 ,而对于Put来说默认是使用@ReqeustBody注解的,如果希望为Put也开启@RequestP ...

  7. c++输入输出,保留几位小数

    #include <iomanip> //头文件 //第一种写法 cout<<setiosflags(ios::); //第二种写法 cout.setf(ios::fixed) ...

  8. 给test函数加个装饰器!

    import timedef timer(func): def deco(*args,**kwargs): start_time=time.time() func(*args,**kwargs) st ...

  9. Centos7 防火墙开放端口,查看状态,查看开放端口

    CentOS7 端口的开放关闭查看都是用防火墙来控制的,具体命令如下: 查看防火墙状态:(active (running) 即是开启状态) [root@WSS bin]# systemctl fire ...

  10. 《手把手教你构建自己的 Linux 系统》学习笔记(1)

    第二章.基础准备--Linux 系统定制原理 Linux 系统的组成及架构 共享库和静态库 在 Linux 系统中,函数库包含两种形式:共享库和静态库. 共享库 共享库在程序运行时,为其提供所需要的函 ...