Binary heap:
I have written binary heaps before, but I rarely use them, so I almost forgot. Recently, I checked some information about the heap, so I am familiar with this data structure again.
A quick and easy way to build a binary heap, using just a simple vector (or array is fine too):
#include "stdafx.h" #include <iostream> #include <vector> #define LeftChild(i) (2*(i) + 1) #define RightChild(i) (2*((i) + 1)) template<class T> void swap(T & a, T & b) { T has = a; a = b; b = has; } class Heap { public: /* filter insert */ void up_insert(int val, std::vector<int> & values, int top); /* Call the upper filter insert to create a heap*/ void up2build(std::vector<int> & values); /* lower filter insert */ void down_insert(std::vector<int> & values, int i, int size); /* Call down filter insert to create heap*/ void down2build(std::vector<int> & values); /* heap sort */ void sort(std::vector<int> & values); }; void Heap::up_insert(int val, std::vector<int> & values, int top) { size_t i; for (i = top; i > 0 && values[i >> 1] < val; i >>= 1) values[i] = values[i >> 1]; values[i] = val; } void Heap::up2build(std::vector<int> & values) { int top = 0; for (auto v : values) { up_insert(v, values, top); ++top; } } void Heap::down_insert(std::vector<int> & values, int i, int size) { int last = values[i]; for (int Child; LeftChild(i) < size; i = Child) { Child = LeftChild(i); if (Child != size - 1 && values[Child + 1] > values[Child]) Child++; if (last < values[Child]) values[i] = values[Child]; else break; } values[i] = last; } void Heap::down2build(std::vector<int> & values) { int size = values.size() - 1; for (int i = size >> 1; i >= 0; i--) { down_insert(values, i, size); } } void Heap::sort(std::vector<int> & values) { int size = values.size() - 1; down2build(values); for (int i = size; i > 0; i--) { swap(values[0], values[i]); down_insert(values, 0, i); } } intmain() { Heap heap; std::vector<int> values { 5345,332,2341,498,248,89,239,4825,8,43,9892,872,1843 }; //heap.build(values); heap.sort(values); for (auto v : values) std::cout << v << std::endl; getchar(); return 0; }
up_build is a process in the form of 'up filtering'. The average case time complexity is θ(n), because the up_insert function only takes the average time of θ(1), the worst case is O(lgn), and the space complexity is O(1 );
Down_build is a process in the form of a 'down filter', with a time complexity of O(n) and a space complexity of O(1). Although it is a bit incredible, see the book "Data Structure and Algorithm Analysis" and related issues in Zhihu .
Left-hand heap:
The properties of the left-hand heap: the NPL (null path length - zero path length) of the left child of any node is at least equal to the NPL of the right child, which makes the left-hand heap very unbalanced. The basic operation of left-hand heap is to perform heap merge.
Definition of NPL: The length of the shortest path from any node to a leaf node.
References:
1. "Data Structure and Algorithm Analysis" Chapter 6 - Heap.