首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C++实现二进制堆

在C++中,实现二进制堆的方法如下:

首先,定义一个二进制堆类,包含以下成员变量:

  • 一个std::vector<int>类型的数组,用于存储堆中的元素
  • 一个int类型的变量,表示堆中元素的数量

然后,实现以下成员函数:

  • insert(int value):向堆中插入一个元素
  • extract_min():从堆中取出最小元素
  • decrease_key(int index, int value):将指定位置的元素值减小
  • get_min():获取堆中最小元素

下面是一个简单的实现:

代码语言:cpp
复制
#include<iostream>
#include<vector>

class BinaryHeap {
public:
    BinaryHeap() : size_(0) {}

    void insert(int value) {
        heap_.push_back(value);
        size_++;
        heapify_up(size_ - 1);
    }

    int extract_min() {
        if (size_ == 0) {
            return -1;
        }
        int min_value = heap_[0];
        heap_[0] = heap_[size_ - 1];
        size_--;
        heapify_down(0);
        return min_value;
    }

    void decrease_key(int index, int value) {
        heap_[index] = value;
        heapify_up(index);
    }

    int get_min() {
        if (size_ == 0) {
            return -1;
        }
        return heap_[0];
    }

private:
    void heapify_up(int index) {
        while (index > 0 && heap_[parent(index)] > heap_[index]) {
            std::swap(heap_[index], heap_[parent(index)]);
            index = parent(index);
        }
    }

    void heapify_down(int index) {
        int min_index = index;
        while (2 * index + 1< size_) {
            min_index = 2 * index + 1;
            if (min_index + 1< size_ && heap_[min_index] > heap_[min_index + 1]) {
                min_index++;
            }
            if (heap_[index] <= heap_[min_index]) {
                break;
            }
            std::swap(heap_[index], heap_[min_index]);
            index = min_index;
        }
    }

    int parent(int index) {
        return (index - 1) / 2;
    }

private:
    std::vector<int> heap_;
    int size_;
};

这个实现中,heapify_up()heapify_down()函数分别用于在插入和删除元素时维护堆的性质。parent()函数用于获取指定节点的父节点的索引。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • 数据结构——最大索引(C++和Java实现)

    在上一篇博客中,记录了优先队列——这个数据结构的实现,并且关于的性质我也在上文中介绍过,能用来进行排序,堆排序具有快速(复杂度O(NlogN)),稳定的特点,尤其是非常稳定,因此适用于某些需要排序稳定性的场合...如果在的使用过程中,中的元素的值要改变,则普通对此无能为力,简单的说,如果一个元素如果进入之后,它的值就不能改变了,否则会影响的性质。...所谓索引,简单的说,就是在里头存放的不是数据,而是数据所在的数组的索引,也就是下标,根据数据的某种优先级来调整各个元素对应的下标在中的位置。本质上来说,索引也是,提供的接口。...那么接下来,我们就来尝试用C++和J�ava两种语言来实现索引,注释在代码中写的比较详细。...C++版如下: #include using namespace std; template class IndexMaxHeap { private

    60610

    左式左式代码实现

    1 NULL的节点的零路径长为-1,只有一个子节点或没有子节点的节点零路径长为0 左式 左式是特殊的优先,除了有序性(每个节点的数据小于其子节点)以外,还有具有与零路径长相关的性质:对于左式,要求任一节点的左子节点零路径长大于等于右子节点的零路径长...操作 合并操作 左式的基本操作是合并,合并的递归描述如下: 当输入的两个都是空的,输出空;当有一个是空的,则返回非空的 当两个非空时,比较两个根节点的大小,返回为: 根节点为原较小的根节点...左子树为原较小的跟节点的左子树 右子树为根节点较大的和跟节点较小堆右子树合并的结果 如下图所示: ?...merge_op.png 对于最终结果,可能在根节点上出现不符合左式的性质的情况,出现这种情况时,交换左右子节点即可: ?...merge_change.png 其他操作 有了核心操作合并,优先的其他操作可由合并实现: 插入:通过合并单个节点和现有实现 弹出:将根节点返回,并合并左右子 代码实现 节点数据结构体 type

    950100

    Windows C++破坏场景及分析

    那么让我们一起来看看Windows中的破坏和分析方法。 破坏 在>中比较详细地讲解了的结构,这里我们简单说一说中对象存储的基本结构。...这里我们问一个问题, 当出现上述破坏的时候,会直接报错吗? 并不会,因为此时执行的是内存拷贝操作,并不会做的任何检查操作。...一般出现破坏很大可能是的上溢,那么前一个块是什么?我们先来看看当前块的内容。...这个方法可以帮大家找出一些内存溢出问题,比如查看当前出现错误的块对应的操作代码进行审查,但是具有滞后性,无法在破坏的时刻保留第一现场,在有些场景分析破坏问题仍然非常困难: 比如当前被破坏的块,可能是由前面的块溢出而导致的破坏...相关阅读 > > > 参考 Mario Hewardt / Daniel Pravat的<

    1.2K20

    (Heap)的详细实现

    图1] 的存储 一般都用数组来表示,i结点的父结点下标就为(i–1)/2。...的操作:小根插入元素 插入一个元素:新元素被加入到heap的末尾,然后更新树以恢复的次序。 每次插入都是将新数据放在数组最后。...[图3] 的操作:删除小根堆堆的最小元素 按定义,中每次都删除第0个数据。为了便于重建,实际的操作是将最后一个数据的值赋给根结点,的元素个数-1,然后再从根结点开始进行一次从上向下的调整。...这样中第0个数据又是中最大的数据,重复上述步骤直至中只有一个数据时,数组元素就已经有序。...小根实现 #include using namespace std; const int DefaultSize = 50; template class

    1K40

    C++ 自由存储区是否等价于

    “free store” VS “heap” 当我问你C++的内存布局时,你大概会回答: “在C++中,内存区分为5个区,分别是、栈、自由存储区、全局/静态存储区、常量存储区”。...然而,尽管C++标准没有要求,但很多编译器的new/delete都是以malloc/free为基础来实现的。那么请问:借以malloc实现的new,所申请的内存是在堆上还是在自由存储区上?...基本上,所有的C++编译器默认使用实现自由存储,也即是缺省的全局运算符new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确...我们所需要记住的就是: 是操作系统维护的一块内存,而自由存储是C++中通过new与delete动态分配和释放对象的抽象概念。与自由存储区并不等价。...new所申请的内存区域在C++中称为自由存储区。藉由实现的自由存储,可以说new所申请的内存区域在堆上。 与自由存储区还是有区别的,它们并非等价。

    3.5K70

    实现与堆排序

    前言 本篇旨在介绍二叉树中特殊结构, 以及实现与应用 更多文章 博客主页: 酷酷学!!! 点击关注 一起加油~ 二 . 树的概念及结构 1....将根结点最大的叫做最大堆或大根,根结点最小的叫做最小堆或小根。 简单来说, 首先是完全二叉树, 如果父节点都比子节点大称为大堆, 父节点比子结点小称为小堆....的性质: 中某个结点的值总是不大于或不小于其父结点的值; 总是一棵完全二叉树。 五 . 实现过程 根据如上所述, 逻辑上是二叉树, 物理上可以使用数组来存储. 1....堆排序算法 我们知道, 如果是小堆, 那么顶数据一定是最小的元素, 我们可以让数据导入到一个中, 然后每次获取顶数据, 再删除顶数据, 这样确实可以进行排序, 但是这样空间复杂度为O(N),每次排序还需要进行的创建...的删除操作的时间复杂度为O(logn),其中n为中节点的个数。 的建立操作的时间复杂度为O(n),其中n为中节点的个数。 的查找操作的时间复杂度为O(1)。 完

    7010

    用大顶实现数据排序

    分为大顶和小顶 大顶 每个节点的值都大于或等于其左右孩子节点的值 小顶 每个节点的值都小于或等于其左右孩子节点的值 堆排序 堆排序是选择排序的一种,最好最坏平均时间复杂度均为 O(nlogn...),不稳定排序 如何实现大顶 比如数组: [4,6,8,5,9] 1. ?...大顶堆排序代码实现 /** * @author shengjk1 * @date 2020/5/31 */ public class HeapSort { public static void...根据升序降序需求选择大顶或者小顶 for (int i = arr.length / 2 - 1; i >= 0; i--) { adJustHeap(arr, i, arr.length...); } /* 2.将顶元素与末尾元素交换,将最大元素沉到数组末端 3.重新调整结构,使其满足定义,然后继续交换顶元素与当前数组的末尾元素 反复执行 调整交换,直到整个序列有序

    43720

    TypeScript实现二叉

    本文将详解二叉并用TypeScript将其实现,欢迎各位感兴趣的开发者阅读本文。...写在前面 本文重点讲解如何实现,对这种数据结构不了解的开发者请移步我的另一篇文章:数据结构: 实现思路 二叉是一种特殊的二叉树,二叉也叫,它有以下两个特性: 它是一颗完全二叉树 二叉不是最小堆就是最大堆...下图描述了一颗完全二叉树: 最小堆和最大堆 最小堆:所有的节点都小于等于它的子节点 最大堆:所有的节点都大于等于它的子节点 下图描述了最大堆和最小堆 实现二叉 二叉堆有两种表现方式: 像二叉树一样用节点表示...extract函数不接收参数 如果为空则返回undefined 如果的长度为1,直接返回顶元素 否则,声明一个变量保存顶元素 执行下移函数调整堆结构 返回刚才保存堆堆顶元素 下移操作的实现: siftDown...实现代码 上面我们讲解了的概念,分析了的实现思路,接下来我们将上述实现思路转化为代码 新建Heap.ts文件 声明MinHeap类,声明、比对函数、初始化 export class MinHeap

    58220
    领券