Heap sorting, first to understand what the heap is here, the heap is actually a binary tree, very image is not, complete two fork tree from the beginning, is a triangle, can also be seen as a "heap."
one, array conversion piles
So the first thing to solve is to sort the arrays and convert them into binary trees. Conversion method
array int a[], containing element a[0],a[1],a[2],a[3] ..... Wait a minute.
Convert to Binary tree:
figure or comparative image, in fact, is in turn from the top of the heap down row, but there is a principle that the upper layer is not full, the next layer will not have elements, limited to fill up a layer, only consider the next layer.
second, how to sort the heap
So the second question comes, how can we sort it out.
Before considering this problem, we need to do some pre-order work first:
1. What is the parent node of a heap that is known to be an element of a[i]? Where are the left and right child nodes (if any)?
It is not difficult to see that if, as we do, the array sequence number starts from 0, the parent node of element A[i] (of course I is not equal to 0 o'clock) is a[(i+1)/2-1], and the left and right child nodes are a[2*i+1] and a[2*i+2];
2, introduce the concept of large root heap.
Dagen: All except the root node and the single a[i] are satisfied: a[parent (i)]>=a[i], where parent (i) represents the subscript value of the parent node of I; Obviously if we turn a tree into a big heap, We can get the maximum value of the current tree, which is the value of the top node of the heap, which is known by the nature of the Dagen.
3, for a left and right sub-tree is already Dagen root node, how to use the node as the root of the two-fork tree to convert to a large heap?
Obviously, if the root node is larger than the left and right child nodes, it is already a large heap
If the root node is smaller than the left and right child nodes, or smaller than one of them? We need to swap the largest child node with the root node, but this is not complete, because the original root node is swapped to its immediate child node location, it does not necessarily meet the Dagen condition limit, if not satisfied, we need to continue the work just now;
Take a look at the following code:
/** * In the case of the left and right subtree are Dagen, the formation of a new large root heap */void maxheapindex (int a[], int root, int maxSize) {//Get left Dial hand node subscript int L = leftchildindex (root); Get the subscript int r = Rightchildindex (root) of the right child node, or//the default maximum node's subscript value is the current root node int largest = root;//if the left node exists and the value of the left node is greater than the root node, the maximum tag value is the left node if (l <= maxSize && a[l] > A[root]) {largest = L;} If the left node exists and the value of the right node is greater than the root node, the maximum tag value is the right node if (R <= maxSize && A[r] > a[largest]) {largest = R;} After the token is determined, if the maximum value is not really the root node, then the value is exchanged, and the recursive call to see if the root node after the swap satisfies the large heap property if (root! = largest) {swap (A + root, a + largest); Maxheapindex (A, largest, maxSize);}} /* * Swap */void swap (int* A, int* b) {int tmp = *A;*A = *B;*B = tmp;} /* * Get Left Dial hand node subscript */int leftchildindex (int i) {return (i + 1) * 2-1;} /* Get subscript */int rightchildindex (int i) {return (i + 1) * 2 for right child node;}
4. The subscript relationship of nodes in the heap.
after 3rd, it's done. In the case that the left and right sub-trees are Dagen, a new Dagen is formed; So how do we get a heap that has not been processed to form a big heap? How to find the left and right sub-trees are Dagen situation? Can not find, so rather than first left and right sub-tree, that is the leaf node, leaf nodes have no left and right subtree, in other words they are natural single-node Dagen; So the parent node of the leaf node satisfies 3 hypothetical conditions, so for a heap, what is the range of the index of the parent node of the leaf node?
for a full-node binary tree, if there is an H layer, such as middle to a[15], there are three layers, for the H-layer of the full-node binary tree, its number of nodes is 2*2^h-1,2^h or 2 of the H power, the number of leaf nodes is 2^h, and the number of nodes other than the leaf node is 2 A ^h-1. It is not difficult to conclude that if the array subscript starts from 0, the subscript range of nodes other than the leaf node should be [0,2^h-2].
So we just need to start with the node in the 2^h-2 position, the rightmost node of the penultimate layer. For heaps with a height of h and N for nodes, H and N have the following relationship: H= is not less than the nearest integer of LGN; knowing that, we can start from the 2^h-2 position until the 0-bit loop executes 3rd to form a large root heap:
/** * Generate a large root heap, thinking: * Starting from the rightmost node of the penultimate layer, calling Maxheapindex * */void maxheapbuild (int a[], int len) {//Get the height int h = log2 (len);//Get The largest subscript value available is int max = (int) (POW (2, h))-2;//loop call for (int i = max; I >= 0; i--) {Maxheapindex (A, I, len-1);}} /** * Get log2 as the bottom value */int log2 (int i) {//ceil function returns an integer not less than a value return (int) ceil (log (i)/log (2));}
Third, the heap sequencing process
After four steps above, we can already get a big heap, and the next job is to use the big heap to sort it out.
for Dagen, the only thing we can be sure of is that the element at the top of it must be the largest element in the current heap, so we can exchange the top element with the rightmost leaf node and the last leaf node each time, then take out the maximum and subtract one of the nodes of the heap. And then re-set the vertex, the leaf node that was swapped to the vertex position above 3, the operation of the above, to re-make the new heap into a large heap, and then we loop through the above operation, until we take out all the elements in the heap, so that we from the beginning to the last removed elements are in the order from large to small, The sorting is done.
The code for this step is simple:
/* Heap Sorting, Idea: * First maxheapbuild, make the root node the maximum value * then the root node and the last node's value is exchanged * then the last node is disconnected (maxsize-=1) * and then maxheapify, Because this time the root node of the left and right sub-tree is still a large heap, so only need maxheapify and do not need maxheapbuild * So from n-1 start cycle to 2 can */void maxheapsort (int a[], int maxSize, int Tmp[]) {Maxheapbuild (A, maxSize);//nfor (int i = maxSize; i > 0;) {//Loop n-1 times Swap (A, a + i); Tmp[i] = a[i];i--;if (i = = 0) {Tmp[0] = a[0];} else {Maxheapindex (a, 0, i);//logn performed n-2 Times}}for ( int i = 0; I <= maxSize; i++) {A[i] = Tmp[i];}}
iv. Complexity of heap sequencing time
for the heap sorting algorithm, we simply look at its time complexity, a maxheapbuild time complexity is N, and then the loop n-1 maxheapindex time complexity is NLOGN, the cyclic assignment operation complexity is n, so calculate, The complexity of time is nlogn.
Algorithm base five (heap sort)