堆结构(heap)

阿里笔试题:

【0、2、1、4、3、9、5、8、6、7】是以数组形式存储的最小堆,删除堆顶元素0后的结果是()

【2、1、4、3、9、5、8、6、7】
【1、2、5、4、3、9、8、6、7】
【2、3、1、4、7、9、5、8、6】
【1、2、5、4、3、9、7、8、6】

 

应选D,不会的朋友可以先阅读下文。

 

以下是参考维基百科对堆的解释:

(英语:Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。在队列中,调度程序反复提取队列中第一个作业并运行,因为实际情况中某些时间较短的任务将等待很长时间才能结束,或者某些不短小,但具有重要性的作业,同样应当具有优先权。堆即为解决此类问题设计的一种数据结构。

堆一般是一个完全二叉树,具有以下性质:

1.任意节点小于或等于(大于或等于)它的所有后裔,最小元(或最大元)在堆的根上(堆序性)(左子节点“不一定”要大于右子节点)。对应为最小(最大堆)。

2.堆总是一棵完全树。即除了最底层,其他层的节点都被元素填满,且最底层尽可能地从左到右填入。

将根节点最大的堆叫做最大堆大根堆,根节点最小的堆叫做最小堆小根堆。常见的堆有二叉堆斐波那契堆等。

堆(通常是二叉堆)常用于排序。这种算法称作堆排序。主要运用堆的排序以选择优先。

下面演示最小堆堆顶元素被删除后的自适应过程:用数组来表示该堆:1,4,2,7,9,5,8

143242_1rSf_2708044.png

堆顶元素1被删除后,最后一个元素8填补堆顶的空缺:

143540_A4vb_2708044.png

堆顶8与其两个子节点4、2比较,选最小的与堆顶互换,如果堆顶就是最小的,则结束:

143752_Jg0c_2708044.png

节点8所在的节点继续与其子节点比较,重复上一步骤,直到满足:任意节点小于或等于它的所有后裔

144013_R67N_2708044.png

至此,结束。用数组来表示该堆:2,4,5,7,9,8

最大堆的形式与之相反,是要满足:任意节点大于或等于它的所有后裔

 

转载于:https://my.oschina.net/henryking/blog/692372

### C++ 中 Heap 数据结构的实现用法 #### 1. 堆的概念及其特性 堆是一种特殊的完全二叉树,分为最大堆和最小堆两种形式。在最大堆中,父节点的关键字总是大于或等于子节点关键字;而在最小堆中则相反。这种性质使得堆成为优先队列的理想选择[^3]。 #### 2. 使用 STL 容器适配器 `priority_queue` 实现堆 C++ 提供了标准模板库(STL),其中包含了可以直接使用的堆——即优先级队列(priority queue)。下面是一个简单的例子来展示如何利用 `std::priority_queue<int>` 来建一个整数的最大堆: ```cpp #include <iostream> #include <queue> int main() { std::priority_queue<int> max_heap; // 插入元素到堆中 int array[] = {20, 12, 35, 15, 10, 80, 30, 17, 2, 1}; for(auto& elem : array){ max_heap.push(elem); } while (!max_heap.empty()) { std::cout << "Top element is: " << max_heap.top() << '\n'; max_heap.pop(); } } ``` 这段代码展示了通过向 `std::priority_queue<int>` 添加一系列数值并依次取出顶部最大的值的过程[^4]。 对于自定义类型的对象来说,如果想要将其放入堆中,则需要重载小于运算符 `<` 或者提供比较函数作为第三个参数给定造函数。 #### 3. 手动实现简单版本的最大堆类 MaxHeap 除了使用内置的支持外,还可以自己动手编写一个简易版的最大堆类 `MaxHeap`: ```cpp class MaxHeap { private: vector<int> elements; public: void insert(int value); // 向堆里加入新元素 bool empty() const; // 判断当前堆是否为空 int top(); // 获取堆顶元素(最大值) void pop_top(); // 移除堆顶元素 }; void MaxHeap::insert(int value) { this->elements.push_back(value); size_t i = this->elements.size()-1; while(i != 0 && this->elements[parent(i)] < this->elements[i]){ swap(this->elements[parent(i)],this->elements[i]); i=parent(i); } } bool MaxHeap::empty()const{ return this->elements.empty(); } int MaxHeap::top(){ if(!this->empty()){ return this->elements.front(); }else{ throw runtime_error("The heap is empty"); } } void MaxHeap::pop_top(){ if(elements.size()>1){ swap(elements[0],elements.back()); elements.pop_back(); make_heap(elements.begin(),elements.end()); } else if(!elements.empty()){ elements.clear(); } } ``` 上述实现了基本功能的手工最大堆类,包括插入、获取顶端元素以及删除顶端元素等功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值