首页
学习
活动
专区
工具
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

58310

左式左式代码实现

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

913100

Windows C++破坏场景及分析

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

1K20

(Heap)的详细实现

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

95340

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.3K70

用大顶实现数据排序

分为大顶和小顶 大顶 每个节点的值都大于或等于其左右孩子节点的值 小顶 每个节点的值都小于或等于其左右孩子节点的值 堆排序 堆排序是选择排序的一种,最好最坏平均时间复杂度均为 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.重新调整结构,使其满足定义,然后继续交换顶元素与当前数组的末尾元素 反复执行 调整交换,直到整个序列有序

39720

【数据结构】实现

前言 在上一篇关于树和二叉树的博客中,最后提到了。有小根和大根。 左边的结构是我们想象出来的,右边才是实际存储的结构。 这次来实现。 2....实现 用数组来实现,这里以实现小堆为例子,它的特点是父节点小于子节点。 先定义一个的结构体:为了方便扩容,加了size。...2.2.2 插入代码实现 先判断空间是否足够,不够就扩容,够就直接插入x,再将php->size++。...2.3.1 分析 这时删除顶的数据,那么顶就是次小的值。 这里要保持删除之后还是小堆。 如果使用挪动数据覆盖,删除根,此时整棵树的父子关系全乱了,大小关系也乱了,这样是不可行的。...2.3.2 删除代码实现 首尾交换删除,然后将php->size--,最后向下调整。

11710

小根的Java实现

是完全二叉树的数组形式,由于没有指针指向,所以可以利用下标来模拟指向,假设 i 为父节点,那么 2i+1 为左孩子,2i+2 为右孩子。...假设 i 为当前节点,那么 (i - 1) / 2 为父节点 根据大小排序可分为小根和大根,小根即元素越小越在上方,大根则相反。...的应用: 堆排序 优先级队列 快速找最值 2....小根实现 内部操作有: 上浮:将小的元素往上移动、当插入元素时,将元素插入末尾,这样上移即可调整位置 下沉:将大的元素向下移动、当删除元素时,将首位交换,弹出尾部,首部下移即可调整位置 插入:添加元素...// 实际存放元素个数 // 这里是个坑,debug了好久,起因:下标 = 实际大小-1 private int size; // 数组存储元素 // 可以实现简单扩容

2.1K30

TypeScript实现二叉

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

54420
领券