基本描述
比赛: 2020年的东京奥运会 男子4*100米接力赛中的兔子队 就是更好的典型的例子
当时约翰牛牛使用兴奋剂被判罚剥削银牌, 然而第四名兔子队顺利获得2020年的东京奥运会 男子接力赛 铜牌
这个事情告诉我们什么?
如果因为第二个人没有资格那么,第三个变成第二个,第四个变成第三个,
只要违反规矩,你就失去了资格,No只是很现实的规矩 但只是数据结构算法,有没有这个数据结构呢?
当然有那就是堆
原本的4x100m接力
现在的4x100m接力
优先队列
医院排队缴费墙上写着"老人或者拥有军人证书的"请到第一窗口"进行缴费"这就是优先级
以前高铁站缴费也要排队,但只要有残疾人或者老人,拥有军人证书的军人,就会优先服务
当然我们的视频网站也是优先队列 只能充值才能去除广告
还有只是在PC和Android or iOS上并没有 电视版本 还得充值 才能看电视它家的优质内容,
堆的原理精讲
顺序表树形化
堆的特性
堆顶 是唯一的出口,也就是顺序表的第一个元素,
堆底 是唯一的入口,也就是顺序表的第n个元素,
堆的根节点:0
堆的当前节点 :i
堆的父节点 :(i-1)/2; 当前节点i 可以是根节点
0-1==(-1)/2; 还是0
当前节点 i=5 它的父节点计算结果为: (5-1)/2 ==2
堆的左子节点: 2*i+1
堆的右子节点: 2*i+2
当前节点 i ==3 (2x3)+1 ==7 左子节点 (2x3)+2 ==8 右子节点
最大堆 和 最小堆 的特性
最大堆 特性 :
- 每个节点都有两个子节点
- 根节点的数据是在堆里是最大的,而且每一个节点都比子节点都大
- 除了根节点没有兄弟节点,最后一个左子节点可以没有兄弟节点之外 其他的必须要有兄弟节点
最小堆 特性 :
- 每个节点都有两个子节点
- 根节点的数据是在堆里是最小的,而且每一个节点都比子节点都小
- 除了根节点没有兄弟节点,最后一个左子节点可以没有兄弟节点之外 其他的必须要有兄弟节点
堆的算法实现
最大堆实现
最大堆声明
ifndef __MAXHEAP_H__
#define __MAXHEAP_H__
using Element_Type = user-defined;
//必须为第一个比第二个还要小
using LessCompare = bool (*)(const Element_Type&, const Element_Type&);
//弹出堆顶元素并且保存Topvalue,要想判断弹出的堆元素合法性通过is_error 判断
struct HeapTopPair {
bool is_error;//true is No error else error
Element_Type Topvalue;
};
//最大堆
struct MaxHeap{
Element_Type* SqeList;
size_t size;
size_t capacity;
LessCompare lessCompare;//对比函数
};
using Heap = struct MaxHeap;
const size_t Default_Capacity = 1000;
//初始化最大堆实例
void initHeapInstance(Heap& heap, LessCompare lessCompare, size_t capacity = Default_Capacity);
// 制造最大堆 heap必须为空 才能制造
void makeHeap(Heap& heap, Element_Type array[], size_t Size);
//插入数据到最大堆
void insertHeap(Heap& heap, const Element_Type &value);
//判断是否是空堆
const bool emptyHeap(const Heap& heap);
//弹出堆顶元素并且删除
HeapValuePair popHeap(Heap& heap);
//返回堆的大小
size_t Heapsize(const Heap& heap);
//判断是否有错误
const bool isHeapError();
//销毁堆
void destroyHeap(Heap& heap);
//获取堆的错误 ,并且以字符串方式返回
const char* &getHeapInstanceError(void);
#endif
最大堆实现
#include"MaxHeap.h"
//堆的实例错误
enum HeapInstanceError {
No_error,
init_error,
make_error,
empty_error,
insert_error,
pop_error
};
struct HeapInstanceErrorState {
HeapInstanceError errorState;
const char* errorvalue;
};
static HeapInstanceErrorState HeapinstanceErrorState = {
No_error ,};
void initHeapInstance(Heap& heap, LessCompare lessCompare, size_t capacity){
HeapInstanceError &error = HeapinstanceErrorState.errorState;
heap.lessCompare = lessCompare;
capacity = capacity > Default_Capacity ? capacity : Default_Capacity;
try {
if (capacity != size_t(-1)) {
heap.SqeList = new Element_Type[capacity];
heap.capacity = capacity;
heap.size = 0u;
}else {
error = init_error;
}
}catch (...){
error = init_error;
}
}
void makeHeap(Heap& heap, Element_Type array[], size_t arraySize){
if ((arraySize < heap.capacity) && (arraySize > 0) && array && emptyHeap(heap)) {
Element_Type *sqeList = heap.SqeList;
size_t &size = heap.size;
while (size != arraySize) {
*(sqeList) = array[size];
sqeList += 1;
++size;
}
for (int i = (size-1) / 2; i >= 0;--i ) {
DownwardAdjustment(heap, i);
}
return ;
}
HeapinstanceErrorState.errorState = make_error;
}
void insertHeap(Heap& heap, const Element_Type& value){
if (heap.size>=heap.capacity){
HeapinstanceErrorState.errorState = insert_error;
return;
}
int index = heap.size;
heap.SqeList[index] = value;
++heap.size;
UpwardAdjustment(heap, index);
}
const bool emptyHeap(const Heap& heap){
return !(heap.size);
}
HeapValuePair popHeap(Heap& heap){
HeapValuePair Pair;
do{
Pair.is_error = true;
if (emptyHeap(heap)) {
Pair.is_error = false;
break;
}
Element_Type TopValue= *heap.SqeList;
Pair.value = TopValue;
*heap.SqeList = *(heap.SqeList + (--heap.size));
*(heap.SqeList + (heap.size)) = TopValue;
DownwardAdjustment(heap, 0);
} while (false);
if (!Pair.is_error) {
HeapinstanceErrorState.errorState = pop_error;
/*throw runtime_error(getHeapInstanceError());*/
}
return Pair;
}
size_t Heapsize(const Heap& heap){
return heap.size;
}
bool isHeapError(