左式堆(数据结构篇)

数据结构之左式堆

左式堆

概念:

  • 左式堆是一种能够高效的支持合并操作的堆 ,左式堆的底层也是由二叉树实现 ,但是左式堆不是平衡的(不由完全二叉树实现的 ),左式堆趋向于不平衡。
  • 左式堆也像二叉堆一样拥有着堆的特性(有序性和结构性),左式堆是最小堆
  • 左式堆是一个拥有堆序性的二叉树(不是二叉堆)加上NPL特性的一棵树 ,任意节点X的NPL(X)(零路径长)为从X到一个没有两个儿子的节点的最短路径的长,因此,具有0个或1个儿子的节点的Npl为0,而Npl(NULL)=-1.

性质:

  • 任意一个节点的零路径长比它的子节点的零路径长的最小值+1
  • 对于堆中的每一个节点X,左儿子的零路径长大于等于右儿子的零路径长
  • 在右路径上有r个节点的左式树必然至少有2r-1个节点
  • 对左式堆的右路径的插入和合并操作可能会破坏左式堆的性质,需要进行调整

合并操作

  • 插入其实就是合并的一个特殊情况
  • 如果两个左式堆合并,有一个堆为空就返回另外一个堆,否则比较两个堆的根值
  • 递归进去 ,我们将大的根值的堆与小的根值的堆的右子堆合并
  • 然后递归返回后,将新的堆作为原来小的根值的堆的右孩子(也叫合并)。
  • 如果这样形成的堆的右子堆的零路径长大于左子堆的,就将左子堆跟右子堆交换,并且更新零路径长,就完成了合并的操作。

实现代码:

cpp 复制代码
#include <iostream>
using namespace std;

struct heapNode{
    int data;    //数据
    heapNode* left;    //左子节点指针
    heapNode* right;   //右子节点指针
    int Npl;     //零路径长
};

class leftheap{
public:
    leftheap(){
        root=new heapNode;
        root->left= nullptr;
        root->right= nullptr;
        root->data=INT_MAX;
        root->Npl=0;
    }
    heapNode* createNode(int data){
        auto p=new heapNode;
        p->data=data;
        p->left= nullptr;
        p->right= nullptr;
        p->Npl=0;
        return p;
    }
    heapNode* merge(heapNode* h1,heapNode* h2){
        if(h1->left== nullptr){
            h1->left=h2;
        }else{
            h1->right= findmerge_node(h1->right,h2);
            if(h1->left->Npl<h1->right->Npl){
                heapNode* p=h1->left;
                h1->left=h1->right;
                h1->right=p;
            }
            h1->Npl=h1->right->Npl+1;
        }
        return h1;
    }
    heapNode* findmerge_node(heapNode* h1,heapNode* h2){
        if(nullptr==h1){
            return h2;
        }else if(nullptr==h2){
            return h1;
        }
        if(h1->data<h2->data){
            return merge(h1,h2);
        }else{
            return merge(h2,h1);
        }
    }
    void insert(int data){
        heapNode* add= createNode(data);
        if(root->data==INT_MAX){
            root=add;
        } else
            root=findmerge_node(root,add);
    }
    void delmin(){
        if(root== nullptr){
            return;
        }
        heapNode* h1=root->left;
        heapNode* h2=root->right;
        delete root;
        root= findmerge_node(h1,h2);
    }
    int getmin(){
        return root->data;
    }
    heapNode* print(heapNode* p){
        if(p!= nullptr){
            cout<<p->data<<" ";
            print(p->left);
            print(p->right);
        }
        return p;
    }
    void print(){
        if(root== nullptr){
            return;
        }
        print(root);
    }
private:
    heapNode* root;
};

尾言

完整版笔记也就是数据结构与算法专栏完整版可到我的博客进行查看,或者在github库中自取(包含源代码)

相关推荐
念越几秒前
题库、练习与错题本代码阅读
开发语言·数据结构
垆边人似月.1 小时前
华为题:盛最多水的容器
数据结构·算法
HPtiger1 小时前
数据结构——插入排序
数据结构·排序算法
All for pursuit.1 小时前
【动态规划-11】279.完全平方数
数据结构·c++·算法·leetcode·动态规划
Logic1012 小时前
C语言/数据结构位运算题解:异或XOR找出套碗游戏中的“幸运碗“——只出现一次的数字
c语言·数据结构·算法·数组·位运算·时间复杂度·空间复杂度
y1su3 小时前
Leetcode 单调栈模板
java·开发语言·数据结构·算法·leetcode
一只旭宝3 小时前
树的家族全景:从二叉树到 B+ 树
数据结构
垆边人似月.3 小时前
华为题:每日温度
数据结构·c++·算法
Peregrine93 小时前
数据结构 - > 树和二叉树
数据结构·算法
j7~3 小时前
【算法】专题四.前缀和:一维二维模板,配套 LeetCode 真题,结合同余定理、哈希前缀和,搞定子数组与子矩阵区间求和问题。
数据结构·c++·算法·前缀和·优选算法