Heap, down-adjusting algorithm, up-adjusting algorithm, array building algorithm, heap sorting, reasoning about the time complexity of heap building

1. Heap

Big root heap: all parent nodes are greater than or equal to child nodes
Insert picture description here

Small root heap: The nature of all parent nodes less than or equal to the child node
Insert picture description here
heap:

• The value of a node in the heap is always not greater than or not less than the value of its parent node

• Heap is always a complete binary tree

2. Implementation of the heap

For the realization of the heap, please click -> Realization of the heap

Now we give an array, which is logically regarded as a complete binary tree. We can adjust it into a small pile through the downward adjustment algorithm starting from the root node.
int a[] = {27,15,19,18,28,34,65,49,25,37};

2.1 Heap downward adjustment algorithm (build small heap)

Downward adjustment algorithm-premise: the left and right subtrees of the current tree must be a small pile
. The core idea of ​​the downward adjustment algorithm: choose which one of the left and right children, exchange with the father, the small one floats up, the big one sinks , If you want to build a large pile, the opposite is true

The following figure shows a downward adjustment method to adjust the small pile
Insert picture description here

2.2 Implementation of heap downward adjustment algorithm (build small heap)

//堆向下调整算法
//建小堆
void AdjustDown(int* a, int n, int root)
{
    
    
	int parent = root;
	int child = parent * 2 + 1;
	//孩子超过数组下标结束
	while (child < n)
	{
    
    
		//child始终左右孩子中小的那个
		if (a[child + 1] < a[child] && child + 1 <n)//防止没有右孩子
		{
    
    
			++child;
		}
		//小的往上浮,大的往下浮
		if (a[child] < a[parent])
		{
    
    
			int tem = a[parent];
			a[parent] = a[child];
			a[child] = tem;
			parent = child;
			child = parent * 2 + 1;
		}
		//中途child>parent则已满足小堆,直接break
		else
		{
    
    
			break;
		}
	}
}

2.3 Heap upward adjustment algorithm

Usage scenario: To insert data into the heap, you need to use the upward adjustment algorithm to adjust, because inserting data into the heap is to insert the data into the position subscripted as size. At this time, the small heap (large heap) is not satisfied. Therefore, the heap is required. Its adjustment, the upward adjustment algorithm is similar to the downward adjustment algorithm. Here, taking the small pile as an example, the upward adjustment method only needs to start from the inserted node position and compare it with the parent node. If a[chaild]<a[parent], then Exchange, if a[chaild]>=a[parent], it means that the out-of-bounds meets the small heap, and break directly

Insert a data as shown in the figure below and use the upward adjustment method to adjust
Insert picture description here

2.4 Upward adjustment algorithm (build small pile) implementation

//堆的向上调整算法
//建小堆
void AdjustUp(HPDataType* a, int child)
{
    
    
	int parent = (child - 1) / 2;
	while (child > 0)
	{
    
    
		if (a[child] < a[parent])
		{
    
    
			int tem = a[parent];
			a[parent] = a[child];
			a[child] = tem;
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
    
    
			break;
		}
	}
}

2.5 Array building algorithm (build small heap)

If the left and right subtrees are not small piles-find a way to treat the left and right subtrees into small piles,
starting from the position of the first non-leaf node from the bottom to adjust downwards

As shown in the figure below, it can be adjusted downwards according to the steps in the figure. The
subscript of the last non-leaf node is (n-1-1)/2
Insert picture description here

2.6 Implementation of array building algorithm (building small heap)

	int n = sizeof(a) / sizeof(int);
	//数组建堆算法
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
    
    
		AdjustDown(arr, n, i);
	}

2.7 Heap sort (descending order)

Below we sort the small heap built above in descending order

The core idea of ​​heap sorting (descending order): Because the smallest number that is the root node can be selected to build a small heap, we will exchange the last leaf node and the root node of the small heap built each time, and the last number will not be exchanged after the exchange. Regarding the data in the heap, the left and right subtrees of the root are still a large heap at this time, and then we use the downward adjustment algorithm to select the next smallest such loop until there is one number left in the heap.

• 升序建大堆
• 降序建小堆

2.8 Implementation of Heap Sort (Descending Order)

//降序
void HeapSort(int* a, int n)
{
    
    
	//建小堆
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
    
    
		AdjustDown(a, n, i);
	}
	int end = n - 1;
	//把最小的换到最后一个位置,不把最后一个数看作堆里的
	//每次选出剩下数中最小的
	//从后往前放
	while (end > 0)
	{
    
    
		int tem = a[end];
		a[end] = a[0];
		a[0] = tem;
		//选出次小的数
		AdjustDown(a, end, 0);
		--end;
	}
}

2.9 Time complexity of building a reactor

The worst case and full binary tree, and each node needs to be adjusted.
Insert picture description here
From the above deduction process, the time complexity of building a heap is O(N);
the time complexity of the downward adjustment algorithm is O(log 2 N );
so The time complexity of heap sort is O(N*log 2 N );

Guess you like

Origin blog.csdn.net/weixin_50886514/article/details/114847405