Heap sort (big root heap and small root heap)

(1) What is it?

It is a sorting algorithm suitable for situations with many keywords, such as selecting the first 1000 maximum or minimum values ​​among billions.
If in traditional sorting algorithms (such as bubbling, insertion, etc.), we It is customary to sort the target data as a whole, and then intercept the first 1000 smallest or largest ones.
But we can imagine that our goal is only 1,000 from the beginning, so in fact, the remaining 999,999,000 data, we don't need to know their sorting order at all, we only need to know that they are all compared The maximum value of our 1000 target data must be large.
This is heap sorting.

Its idea is very clear and simple on the whole, and its structure is a complete binary tree.
If the root node is larger than the left and right children, it is called a big root pile. Among them, the root nodes of the left and right children will be larger than their left and right children.
If the root node is smaller than the left and right children, it is called a small root pile. Among them, the root nodes of the left and right children will be smaller than their left and right children.
To put it more simply: all intermediate nodes must be larger than its children (big root pile), or must be smaller than its children (small root pile)

(2) How to build a big root heap

initialization:

1: According to the given array, first construct a binary tree according to the level priority (placed layer by layer)
2: Starting from the root node of the last leaf node of the binary sorting tree, compare the left and right children of the node, Select the largest permutation to the root node
3: arrange the penultimate non-leaf node, compare and select the largest permutation to the root node...
4: and so on, until the complete tree is sorted, at this time the root node of the tree It must be the maximum value 5 in the big root heap
: in the process of pushing the big number up, it also depends on whether the number in the exchange position is larger than the left and right children, if not, then choose the largest one to change to the child root node.

For example: Suppose there is an array [1, 3, 5, 7, 9, 2, 4, 6, 8, 10] requiring the establishment of a large root heap

1: First build a binary tree according to the principle of hierarchical priority (after the tree is generated, it is stored in a one-dimensional array by default according to row traversal, and the subscript of the array starts from 1, that is, the subscript 1 stores the root node 1, and the subscript 2 store left child 2, subscript 3 stores right child 5, and so on)
insert image description here

2: Start from the last non-leaf node of the binary tree, compare the left and right children of the node, and select the largest permutation to the root node How to find the last
non-leaf node of the binary tree: n/2 round down
this example , 10 elements, then 10/2 = 5; that is, the subscript of the last non-leaf node is 5, that is, the subtree whose root node value is 9.
Comparing 9 and 10, it is found that 10 is the largest, so 10 and 9 exchange positions.

3: Arrange the second-to-last non-leaf node, compare and select the largest replacement to the root node...
How to find the second-to-last non-leaf node: n/2 - 1 = 4
is the subscript 4, the root The subtree whose node value is 7
compares 6, 7, and 8, so 7 and 8 exchange positions, and 8 is the root node.


4: By analogy, until the complete tree is sorted, the root node of the tree must be the maximum value in the large root pile at this time. The children are all big, if not, then choose the largest one and switch to the root node of the subtree.
insert image description here

At this point, the construction of the big root heap is completed

Output the top element of the stack:

After outputting 10 at the top of the stack, fix it with [the last leaf node] 1, and find that 1 destroys the nature of the large root heap, so it needs to be adjusted downwards from the root node, that is, compare 1, 9, 5; 9 Put the root node.
1 sinks to the root node of the left subtree, but still does not satisfy the nature of the large root pile, so compare 1, 8, 3; put 8 into the root node of the left subtree, and 1 sinks to the left subtree of the left subtree again Compare 1, 6, and 7 in the root node of the left subtree
; replace 7 with the root node of the left subtree of the left subtree, and sink 1 again.
So far, the readjusted binary tree conforms to the nature of the large root heap again.
insert image description here

Add/insert element operation:

The newly added/inserted elements are to put the new node in the newly generated last leaf node, and then compare the value of the new leaf node data with the value of its parent node to see if the position needs to be changed. If necessary, start to adjust, which is the same operation as initialization.

⚠️ Note that initialization and adding elements are adjusted from bottom to top, while deleting the top element of the stack is adjusted from top to bottom.

Code:

#include <stdio.h>

void HeapSort(int a[], int i, int lenght){
    
    
	/*用以保存子树的根结点*/
	a[0] = a[i];
	/* 按照二叉树性质,不断i*2是不断深入找到下一层的左孩子结点 */
	for(int j=i*2; j<=lenght; j=j*2){
    
    
		/* k是对应子树的右孩子结点,先比较右孩子 */
		int k = j+1; 
		/* 左右孩子比较出一个大值 */
		if(k<lenght && a[k]>a[j]){
    
    
			j = k;
		}
	    /* 判断根结点与左右孩子的最大值谁更大 */
		if(a[0]<a[j]){
    
    
			a[i] = a[j];
			i = j;
		}
	}
	/* 循环退出后,j一定是最适合temp值的地方 */
	a[i] = a[0];
}

int main()
{
    
    
	int a[]={
    
    0,1,3,5,7,9,2,4,6,8,10};
	int lenght = 11;
	/* 从下往上逐个非叶子结点调整 */
	for(int i=lenght/2; i>0; i--) {
    
    
		HeapSort(a,i,lenght);
	}
   
   return 0;
}


Guess you like

Origin blog.csdn.net/whiteBearClimb/article/details/128172814