1. 1. 大/小根堆(优先队列)
    1. 1.1. 原理
    2. 1.2. 特点
    3. 1.3. 实现
      1. 1.3.1. 定义
      2. 1.3.2. 判断是否为空
      3. 1.3.3. 判断是否为满
      4. 1.3.4. 插入
      5. 1.3.5. 获取堆顶元素
      6. 1.3.6. 弹出堆顶元素

大/小根堆(优先队列)

原理

最大(小)堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都大于等于其儿子结点的data域值,并且它是一个完全二叉树。根结点都表示树中的最小元素结点。最大堆的根结点是树中元素最大的。实为二叉树的一种

特点

  • 最大堆的根结点是树中元素最大的
  • 最小堆的根结点是树中元素最小的
  • 兄弟节点之间没有严格的约束关系,可以是左>右,也可以左<右

实现

采用数组的方式存储

以下以大根堆为例子,小根堆同理。

定义

class MaxHeap{
private:
    int cap;
    int size;
    int* data;

public:
    MaxHeap(int MaxSize){
        this->cap=MaxSize;
        this->size=0;
        this->data=new int[MaxSize+1];
    }
    bool empty()
    bool full();
    bool push(int x);
    int pop();
    int top();
};

判断是否为空

bool MaxHeap::empty(){
    if(this->size==0){
        return true;
    }
    return false;
}

判断是否为满

bool MaxHeap::full(){
    if(this->cap==this->size){
        return true;
    }
    return false;
}

插入

bool MaxHeap::push(int x){
    if(this->full()){
        return false;
    }
    this->size++;
    for(int i=this->size;this->data[i/2]<x;i/=2){ //拿x的值和节点作比较,当x比节点值大的时候,不断把指针上升
        this->data[i]=this->data[i/2];// 上滤x
    }
    this->data[i]=x;
    return true;
}

获取堆顶元素

int MaxHeap::top(){
    if(this->empty()){
        return -1;
    }
    return this->data[1];
}

弹出堆顶元素

int MaxHeap::pop(){
    if(this->empty()){
        return -1;
    }
    int parent,child;
    int max_item,x;
    max_item=this->data[1];
    x=this->data[this->size--];
    for(parent=1;parent*2<this->size;parent=child){
        child=parent*2;
        if((child!=this->size)&&(this->data[child]<this->data[child+1])){
            child++;
        }
        if(x>=this->data[child]){
            break;
        }else{
            this->data[parent]=this->data[child];
        }
    }
    this->data[parent]=x;
    return max_item;
}