最大堆:记录一下

#include <iostream>
#include <utility>   
#include <string>
#include <vector>

// 构建最大堆则从 size/2 开始进行下沉

void sink(std::vector<int> &max_heap, int sink_node, int size) {  // 下沉操作
  while (sink_node*2 <= size) {  // 二叉树性质:左孩子为2i
    int j = 2 * sink_node;
    if (j < size && max_heap[j] < max_heap[j+1]) {  // 有右孩子且右孩子更大
      j++;   // 指向最大孩子
    }
    if (max_heap[sink_node] >= max_heap[j]) {
      break;
    } else {  // 下沉结点不是最大,交换
      std::swap(max_heap[sink_node], max_heap[j]);
    }
    sink_node = j;   // 继续下沉
  }
}

void rise(std::vector<int> &max_heap, int size) {  // 一直上浮直到满足最大堆或者到达根
  while (size > 1 && max_heap[size] > max_heap[size/2]) {
    std::swap(max_heap[size], max_heap[size/2]);
    size /= 2;
  }
}

void pop(std::vector<int> &max_heap) {   // 取首元素->首尾交换->弹出尾元素->调整最大堆(下沉)
  std::cout << max_heap[1] << std::endl;
  
  max_heap[1] = max_heap[max_heap.size()-1];
  max_heap.pop_back();
  
  sink(std::forward<std::vector<int>&>(max_heap), 1, max_heap.size()-1);  // 转发,下沉结点, 大小
}

void push(std::vector<int> &max_heap, int val) {
  max_heap.push_back(val);
  rise(std::forward<std::vector<int>&>(max_heap), max_heap.size()-1);  // 最后一个结点进行上浮
}

int main(int argc, char *argv[]) {
  // 操作次数和存放指令
  int count;
  std::string op;
  
  std::cin >> count;
  std::cin.get();    // 读取缓冲的换行符
  
  // 大根堆的数据结构
  std::vector<int> max_heap(1);  // 从一开始编号
  
  while (--count >= 0) {
    std::getline(std::cin, op);   // 读取空格!
    
    if (op.substr(0, 4) == "push") {
      int val = std::stoi(op.substr(5));
      push(max_heap, val);
    } 
    if (max_heap.size() == 1) {  // 空直接跳过本次循环(一位多余)
      std::cout << "empty" << std::endl;
      continue;
    }
    if (op.substr(0, 3) == "top") {
      std::cout << max_heap[1] << std::endl;
    }
    if (op.substr(0, 3) == "pop") {
      pop(max_heap);
    }
  }
  
  return 0;
}