This page looks best with JavaScript enabled

Heap in C++

 ·   ·  โ˜• 4 min read  ·  ๐Ÿฆ‚ Kyle · ๐Ÿ‘€... views

let’s learn how to use heap in C++

func description
make_heap Make heap from range
push_heap Push element into heap range
pop_heap Pop element from heap range
sort_heap Sort elements of heap
is_heap Test if range is heap
is_heap_until Find first element not in heap order

make_heap

make heap from range

We need to have a heap before we operate on a heap, make_heap let’s us rearrange elements in a range.

Usually we use a vector to hold these range of elements:

1
2
3
4
5
6
#include <iostream>     // std::cout
#include <algorithm>    // std::make_heap, std::pop_heap, std::push_heap, std::sort_heap
#include <vector>       // std::vector

std::vector<int> heap{1,2,3,4,5,6,7};
std::make_heap(heap.begin(), heap.end()); // 7 5 6 4 2 1 3

For now, you only need to know that after make_heap, the biggest element is *begin(heap) or heap[0]. Other elements are not necessarily sorted, but arranged in a certain way, to know the detail, see heap in C++ 2.

push_heap

Push element into heap range

Given a heap in the range [first,last-1), this function extends the range considered a heap to [first,last) by placing the value in (last-1) into its corresponding location within it.

Meaning to add an element to a heap:

1
2
heap.push_back(8); // 7 5 6 4 2 1 3 8
std::push_heap(heap.begin(), heap.end()); // 8 7 6 5 2 1 3 4

push_heap will adjust the elements in the new range (old range + 1), and place the added element to where it fits.

pop_heap

Pop element from heap range

Given a heap in the range [first,last), this function rearranges the elements in the heap range [first,last) in such a way that the part considered a heap is shortened by one: The element with the highest value is moved to (last-1).

Meaning to pop out the largest element from the heap:

1
std::pop_heap(heap.begin(), heap.end()); // 7 5 6 4 2 1 3 8

new heap range: [first, last-1)

is_heap

Test if range is heap

simple as description, code:

1
2
3
// heap: 7 5 6 4 2 1 3 8
std::is_heap(heap.begin(), heap.end()); // false
std::is_heap(heap.begin(), heap.end()-1); // true

is_heap_until

Find first element not in heap order

We’ve already popped out 8 from the heap, so:

1
2
3
// 7 5 6 4 2 1 3 8
auto it = std::is_heap_until(heap.begin(), heap.end());
std::cout << *it << std::endl; // 8

sort_heap

Sort elements of heap

Sorts the elements in the heap range [first,last) into ascending order.

This is actually quite simple, you may have as well implement this function yourself, just keep doing pop_heap until the heap is shortened to 1.

1
std::sort_heap(heap.begin(), heap.end() - 1, cmp); // 1 2 3 4 5 6 7 8

Code Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <algorithm>
#include <iostream>
#include <random>
#include <vector>

template <typename T>
void printArr(const std::vector<T> &arr) {
  for (const T &t : arr) std::cout << t << " ";
  std::cout << std::endl;
}

// std::random_device rd;
// std::mt19937_64 urng(rd());

int main(int argc, char const *argv[]) {
  std::cout << "original array" << std::endl;
  std::vector<int> heap(7);
  std::iota(heap.begin(), heap.end(), 1);
  printArr(heap); // 1 2 3 4 5 6 7

  // std::cout << "shuffle" << std::endl;
  // std::shuffle(heap.begin(), heap.end(), urng);
  // printArr(heap);

  // auto cmp = std::greater<int>();
  // auto cmp = std::less<int>();

  std::cout << "make heap" << std::endl;
  std::make_heap(heap.begin(), heap.end());
  printArr(heap); // 7 5 6 4 2 1 3

  std::cout << "push back 8" << std::endl;
  heap.push_back(8);
  printArr(heap); // 7 5 6 4 2 1 3 8

  std::cout << "push heap" << std::endl;
  std::push_heap(heap.begin(), heap.end());
  printArr(heap); // 8 7 6 5 2 1 3 4

  std::cout << "pop heap" << std::endl;
  std::pop_heap(heap.begin(), heap.end());
  printArr(heap); // 7 5 6 4 2 1 3 8

  std::cout << "is heap" << std::endl;
  std::cout << std::is_heap(heap.begin(), heap.end()) << std::endl; // 0

  std::cout << "is heap until" << std::endl;
  auto it = std::is_heap_until(heap.begin(), heap.end());
  std::cout << *it << std::endl; // 8

  std::cout << "sort heap (begin, end-1)" << std::endl;
  std::sort_heap(heap.begin(), heap.end() - 1);
  printArr(heap); // 1 2 3 4 5 6 7 8
  return 0;
}

Refs

Share on