#include <algorithm>
#include <iostream>
#include <vector>

int indice_padre(int i) {
   return (i - 1) / 2;
}

int indice_izq(int i) {
   return 2 * i + 1;
}

int indice_der(int i) {
   return 2 * i + 2;
}

struct cola_prioridad {
   std::vector<int> arr;

   int size( ) {
      return arr.size( );
   }

   bool empty( ) {
      return arr.empty( );
   }

   int top( ) {
      return arr[0];
   }

   void push(int v) {
      arr.push_back(v);
      for (int i = arr.size( ) - 1; i != 0 && arr[indice_padre(i)] < arr[i]; i = indice_padre(i)) {
         std::swap(arr[indice_padre(i)], arr[i]);
      }
   }

   void pop( ) {
      std::swap(arr[0], arr.back( ));
      arr.pop_back( );
      for (int i = 0;;) {
         int indice_max = i;
         for (int indice_hijo : { indice_izq(i), indice_der(i) }) {
            if (indice_hijo < arr.size( ) && arr[indice_max] < arr[indice_hijo]) {
               indice_max = indice_hijo;
            }
         }
         if (indice_max == i) {
            break;
         }
         std::swap(arr[i], arr[indice_max]);
         i = indice_max;
      }
   }
};

int main( ) {
   cola_prioridad cp;
   cp.push(23);
   cp.push(13);
   cp.push(20);
   cp.push(40);
   cp.push(15);

   while (!cp.empty( )) {              // los elementos saldrán del mayor al menor; ordenar un arreglo usando una cola de prioridad es el algoritmo llamado "heap sort"
      std::cout << cp.top( ) << " ";
      cp.pop( );
   }
}
