The content of this chapter is the first of the second part of the "Introduction to Arithmetic" textbook, "Sequencing and sequencing statistics".
Heap sort, which is an O (NLGN) time-based sorting algorithm . It uses a data structure called a heap that can also be used to implement a priority queue.
1, the concept of the heap
Array R[1...N], n keyword sequence k1,k2,...,kn, when and only if the sequence satisfies the following properties (for short, the heap nature, take Dagen as an example):
- Ki >= k (2i) and Ki >= K (2i+1) (1≤I≤N/2) Dagen is replaced by the >= number. A non-leaf node equivalent to a complete binary tree, K (2i) is the left Dial hand node, and K (2i+1) is the right child node.
if the vector stored in this sequence is R[1..N] as a storage structure of a complete binary tree, then the heap is essentially a complete binary tree satisfying the following properties: The keywords of
any non-leaf node in the tree are not greater than (or not less than) the keywords of their children (if any) nodes.
A binary heap is an array that can be seen as an approximate complete binary tree. Each node on the tree corresponds to an element in the array. In addition to the bottom level, the tree is fully filled and is padded from left to right. The array a representing the heap contains two properties: A.length represents the number of array elements, and a.heap_size indicates that array A has the number of elements with a heap structure. There are:0=<a.heap_size=<a.length. A[1] is the root node of the tree.
Usually given node I, we can easily get the parent node of the node and the left and right child nodes according to its position in the array:
- Parent (i) = I/2 //Divide position I by 2 to get the parents of the current node .
- Left (i) = 2*i //Pair position I by 2 to get the left dial hand node of the current node
- Right (i) = 2*i+1. //To position I by 2 plus 1, you can get the right sub-node of the current node.
in a heap-ordered implementation, these three functions are usually implemented in the form of "macros" or "inline functions", such as:
#define PARENT (i) I/2#define left (i) i*2#define right (i) i*2+1
Fig. 1 a) A binary tree, the number inside each node circle is the largest heap shown in the array form of the data b it stores.
depending on the condition that the node values meet, it can be divided into the maximum heap and the smallest heap, the maximum heap and the minimum heap in addition to satisfy the nature of the heap must satisfy:
- The characteristics of the maximum heap are: a[parent (i)] >= a[i] except for each node I in the root node;
- The minimum heap is characterized by a[parent (i)] >=a[i] except for each node I, other than the root node.
In the
heap sorting algorithm, we prefer to select the maximum heap. The minimum heap is typically used to construct a priority queue.
To think of a heap as a tree, as in the following characteristics:
- The height of a heap containing n elements is lgn;
- The operation time of the basic operation on the heap structure is proportional to the tree height, i.e. the time complexity is: O (NLGN);
- When using an array to represent a heap that stores n elements, the last non-leaf node is: N/2; the subscript of the leaf node is: n/2+1,n/2+2,......,n;
- In the largest heap, the largest element is on the root of the subtree, and in the smallest heap, the smallest element is on the root of the child tree.
2. The nature of the maintenance heap
The nature of the maintenance heap, which is referred to here, is mainly that the value of the current node of the maintenance heap is greater than the left child node value and the right child node value. When data changes in the heap, the maintenance function is able to adjust the position of elements in the structure of the tree so that the array can continue to satisfy the nature of the heap.
Here we construct a function: Max_heapify () An important process to maintain the maximum heap properties. When calling Max_heapify (), we assume that the root node is left (i) and right (i) the two-fork tree is the largest heap. Max_heapify () is to "sink" the value of A[i] by the maximum value, thus allowing the following sub-tree of the root node to re-satisfy the nature of the maximum heap.
Figure 2 Max_heapify () function to adjust the execution of the i=2 position element
As you can see, a[2] violates the nature of the maximum heap, because its value is not greater than its children, so it needs to be adjusted. According to the code structure of Max_heapify () in the textbook, I implemented the recursive implementation of C + +, the return value of function max_heapify () is void:
Maintain the nature of the heap: that is, the node I out of the left and right sub-tree value is less than the value of the nodes void max_heapify (int *arr, int length, int i) {int, l, right, largest;int temp;left = leaving (i right = right (i), if (left <= length && arr[left] > arr[i]) largest = Left;elselargest = I;if (right <= l Ength && Arr[right] > arr[largest]) largest = Right;if (i! = largest) {temp = Arr[i];arr[i] = Arr[largest];arr[la Rgest] = temp;max_heapify (arr, length, largest);}}
the time cost of the max_heapify () function includes:
- Time cost of adjusting the relationship between A[left (i)] and a[right (i): O (1);
- Lesson one takes the time cost of running max_heapify () on the subtree of the root node as I.
for a node with a tree height of H, the
time complexity of the max_heapify () function is: O (h).
3. Build a heapbuilding the heap is mainly using the bottom-up method using Max_heapify () to convert an array of size n=a.length A[1.....N] to the maximum heap. A leaf node can be seen as a heap that contains only one element. build the heap pseudo-code:
Build_max_heap (A) 1 a.heap_size=a.length2 for i = a.length/2 downto max_heapify (a,i)
C + + code implementation:
Create heap void build_max_heap (int *arr, int length) {int i;for (i = LENGTH/2; i > 0; i--) {max_heapify (arr, length, i);}}
prove the correctness of Build_max_heap ():
initialization: The first iteration: I=LENGTH/2, other nodes length/2 +1,length/2 +2,......n are leaf nodes. Therefore, the node I=1,......LENGTH/2 is the root node of the trivial maximum heap.
hold: in the For loop, the value of I decrements sequentially, establishing the node length/2-1, ..., 1 of the heap structure.
Terminate: exits the For loop when i=0.
The time complexity of each call to Max_heapify () is O (LGN), and Build_max_heap () requires an O (n) call. So
the total time complexity of build_max_heap () is: O (NLGN). is the process diagram that creates the heap:Figure 3 Build_max_heap () operation
4. Heap Sorting algorithmafter mastering the functions of the max_heapify () function and the Build_max_heap () function, we have the basis of mastering the heap sorting algorithm. heap Sorting algorithm process:
- Using Build_max_heap () to build the largest heap of A[,1......N], where n=a.length;
- Exchange A[1] and a[length] values so that the largest element is in the last position of the heap;
- Heap_size = heap_size-1; Reduce the number of heap elements by 1, that is, exclude the maximum position element from the heap;
- Call Max_heapify () to adjust the structure of the array a[,1.....heap_size] to make it a new structure;
- Repeat steps 2,—— step 4, until you know I=1.
Pseudo Code:
Heapsort (a) 1 build_max_heap (a) 2 for i = a.length downto of Exchange a[1] with a[i]4 a.heap_size = A.heap_size-15 max_heapify (a,1)
C + + code implementation:
Heap sort void Heap_sort (int *arr, int length) {int I, temp;build_max_heap (arr, length); i = Length;while (i > 1) {temp = Arr[i ];arr[i] = arr[1];arr[1] = temp;i--;max_heapify (arr, I, 1);}}
shows the case of the maximum heap before the start of the first iteration of the Heapsort (A) pseudo-code section 2~ line 5th for loop and the maximum heap after each iteration:Figure 4 Operation of Heapsoer
5. A simple exampleaccording to the knowledge points in this chapter, the heap sorting examples are written:
#include <iostream>using namespace std; #define PARENT (i) I/2#define left (i) I*2#define right (i) i*2+1//the nature of the maintenance heap: Even if the node I out of the left and right sub-tree value is less than the value of the nodes void max_heapify (int *arr, int length, int i) {int, right, largest;int temp;left Right (i), if (left <= length && arr[left] > arr[i]) largest = Left;elselargest = I;if (right <= length &am p;& Arr[right] > arr[largest]) largest = Right;if (i! = largest) {temp = Arr[i];arr[i] = Arr[largest];arr[largest] = Temp;max_heapify (arr, length, largest);}} Create heap void build_max_heap (int *arr, int length) {int i;for (i = LENGTH/2; i > 0; i--) {max_heapify (arr, length, i);}} Heap sort void Heap_sort (int *arr, int length) {int I, temp;build_max_heap (arr, length); i = Length;while (i > 1) {temp = Arr[i ];arr[i] = arr[1];arr[1] = temp;i--;max_heapify (arr, I, 1);}} int main () {int arr[11] = {NULL, 0, 5,, at,%, 12};cout << "----------------Heap sort------------------ --"<< endl;cout <<" before sorting: "; for (int i = 1; I < 11; i++) cout << arr[i] << ""; cout << Endl;heap_sort (arr.); cout << "after sorting:"; for (int i = 1; I < 11; i++) cout << arr[i] << ""; cout << endl;system ("pause"); return 0;}
program Run Result:
Introduction to Algorithms Learning summary chapter-6--heap sequencing