Heap
Priority queue: for a special queue, the order of taking out elements is based on the priority (keyword) size of elements, not the order in which elements enter the queue
The priority queue is realized by array or linked list
Array:
- Insert, element always inserts tail O(1)
- Delete, find the maximum (or minimum) keyword O(n), and delete the element O(n) to be moved from the array
Linked list
- Insert, the element is always inserted into the head O(1) of the linked list
- Delete, find the maximum (or minimum) keyword O(n), and delete node O(1)
Ordered array
- Insert, find the appropriate location O(n) or O(log2(n)), move the element and insert
- Delete, delete the last element O(1)
Store with binary tree
Binary tree structure is adopted, with emphasis on deleting the maximum value
Heap, implemented with a complete binary tree, satisfies that any node value is greater than your node value on the left and right sides of it
Heap has two characteristics
- Structure, a complete binary tree represented by an array
- In order, the keyword of any node is the maximum or minimum value of all nodes of its subtree
- Maximum heap, large top heap, maximum
- Minimum heap, small top heap, minimum
- Ordering of node sequence on the path from root node to any node
The data object set is a complete binary tree. The element value of each node is not less than that of its child nodes
Main operation
MaxHeap Crearte(int maxsize): creates an empty maximum heap
Boolean IsFull(MaxHeap H): judge whether the maximum heap H is full
Insert(MaxHeap H, elementtype item): insert the element item into the maximum heap H
Boolean IsEmpty(MaxHeap H) to judge whether the maximum heap H is empty
ElementType DeleteMax (MaxHeap H), returns the largest element in H (high priority)
Heap creation
struct heapstruct { element* elements;//An array that stores heap elements int size;//Current number of elements in the heap int capacity;//Maximum heap capacity };
maxheap create(int maxsize) { //Create empty Max stack with maxsize capacity maxheap h = (maxheap)malloc(sizeof(struct heapstruct)); h->elements = (element*)malloc((maxsize + 1) * sizeof(int)); h->size = 0; h->capacity = maxsize; h->elements[0] = maxdata; //The sentinel is defined as a value greater than all possible elements in the heap for faster operation in the future return h; }
Heap insertion
//Maximum heap insertion //Algorithm: insert the new node into the ordered sequence from its parent node to the root node void insert(maxheap h, element item) {//Insert the element item into the maximum value h, where h - > elements [0] has been defined as sentinel int i; if (isfull(h)) { cout << "Maximum heap full" << endl; return; } i = ++h->size;//i points to the position of the last element in the heap after insertion for (; h->elements[i / 2] < item&&i>1; i /= 2)//i is used to indicate the current location to be placed. The parent node is i/2 { h->elements[i] = h->elements[i / 2];//Downward filtering node } h->elements[i] = item;//Insert item into }
Deletion of heap
//Deletion of maximum heap //Take out the element of the root node (maximum value), delete a node of the heap, and replace the element of the root node with the element of the next value element deletemax(maxheap h) { //Extract the element with the largest key value from the maximum heap h and delete a node int parent, child; element maxitem, temp; if (isempty(h)) { cout << "Maximum heap empty" << endl; return; } maxitem = h->elements[1]; //Take out the maximum value of the root node and save the tree root element to be deleted //Use the last element in the maximum value to filter the lower nodes from the root node upward temp = h->elements[h->size--]; for (parent = 1; parent * 2 <= h->size; parent = child) {//Parent * 2 < = H - > size judge whether there are left and right sons child = parent * 2;//Child points to the left son, and child+1 points to the right son if ((child != h->size) && (h->elements[child]) < h->elements[child + 1]) {//Child! = H - > size judge whether there is a right son //Child points to the larger of the left and right child nodes child++; } if (temp >= h->elements[child]) { break; } else {//Move temp element to the next level h->elements[parent] = h->elements[child]; } } h->elements[parent] = temp; return maxitem; }
Establishment of maximum heap
- Create maximum heap: store the existing N elements in a one-dimensional array according to the requirements of the maximum heap
- Through the insertion operation, N elements are successively inserted into an initially empty heap, and the maximum time cost is O(NlogN)
- Establishing maximum heap under linear time complexity
- The N elements are stored in the input order to meet the structural characteristics of the complete binary tree
- Adjust the position of each node to meet the ordered characteristics of the maximum heap
Huffman tree and Huffman coding
Convert a 100 point test score into a five point score
According to the different search frequencies of nodes, a more effective search tree is constructed
Definition of Huffman tree
Weighted path length (WPL): let the binary tree have n leaf nodes, each leaf node has a weight wk, and the length from the root node to each leaf node is lk, then the sum of the weighted path lengths of each leaf node is:
W
P
L
=
∑
i
=
1
n
w
k
l
k
WPL=\sum_{i=1}^{n}{w_kl_k}
WPL=i=1∑nwklk
Objective: to minimize the weighted path length
Optimal binary tree or Huffman tree: the smallest binary tree in WPL
Construction of Huffman tree
Each time the two binary trees with the smallest weight are merged to form a new binary tree
Characteristics of Huffman tree
-
There is no node with degree 1
-
The Huffman tree with n leaf nodes has 2n-1 nodes
n0: total number of leaf nodes
n1: total number of nodes with only one son
n2: total number of nodes with 2 sons
n2=n0-1
- The left and right subtrees of any non leaf node of a Huffman tree are still Huffman trees after being exchanged
- For the same set of weights, two Huffman trees with different structures can be generated, but the whole WPL value will be the same
Huffman coding
Given a string, how to encode characters can minimize the encoding storage space of the string
How to avoid ambiguity:
Prefix code: the code of any character is not the prefix of another character code
It can be decoded without ambiguity
Coding with binary tree
- Left and right branches: 0, 1
- Characters are only on leaf nodes
Constructing with Huffman tree
Representation of sets
Set operation: intersection, union, complement and difference to determine whether an element belongs to a set
Joint query set: what set does an element belong to when a set is merged or subtracted
A set can be represented by a tree structure, and each node in the tree represents a set element
Parent representation: children point to their parents
Using array storage
Set operation
Find operation: find the set where an element is located (represented by the root node)
Union of sets:
- Find the root node of the set tree where x1 and x2 elements are located respectively
- If they are different roots, set the parent node pointer of one root node to the array subscript of the other root node
In order to improve the efficiency of searching after merging, small sets can be merged into relatively large sets
#include<stdio.h> #include<iostream> using namespace std; typedef int element; typedef struct { element data; int parent; }settype; const int maxsize=1000; int find(settype s[], element x) {//Find the collection to which the element with value x belongs in the array //maxsize is a global variable and is the maximum length of array s int i; for (i = 0; i < maxsize && s[i].data != x; i++); if (i >= maxsize) return -1;//x not found, - 1 returned for (; s[i].parent >= 0; i = s[i].parent);//When the value of parents is equal to - 1, the root node is found return i;//Find the set to which x belongs, and return the subscript of the tree root node in the array s } void union_set(settype s[], element x1, element x2) { int root1, root2; root1 = find(s, x1); root2 = find(s, x2); if (root1 != root2) { s[root2].parent = root1; } }
Path in heap
Insert a series of given numbers into a small top heap h [] that is initially empty, and then print the path from H[i] to the root node for any given subscript I
The heap is often represented in the form of an array
#include<iostream> #include<stdio.h> #define MAXN 1001 #define MINH -10001 using namespace std; int h[MAXN]; int h_size; //Heap initialization void create() { h_size = 0; h[0] = MINH; //Set up sentry posts } void insert(int x) { int i; //Because the position of 0 has been put into a minimum value, the subscript will not exceed 1 for (i = ++h_size; h[i / 2] > x; i /= 2) h[i] = h[i / 2]; h[i] = x; } int main() { int n, m, i, j,x; create(); for (i = 0; i < n; i++) { cin >> x ; insert(x); } for (i = 0; i < m; i++) { cin >> j; cout << h[j]; while (j > 1) { j /= 2; cout << h[j]; } cout << endl; } return 0; }