[Data structure]——Heap sort

Preface: We have learned about heaps and implemented heaps, so let's sort the heaps. How do we sort it? This time we will solve the problem.

Insert image description here

If our heap sort requires sorting, should we build a large heap or a small heap? If we build a small heap, then we will continue to build heaps during sorting, and then our time complexity will be very large. If we build a big heap, the largest number will be at the top of the heap. If we want to sort the next ones, and we ask for ascending order, our big heap can easily solve this problem. We only need to sort the numbers at the top of the heap. Just exchange it with the last number and continue to adjust downwards. The time complexity is very small, so we create a large pile when sorting in ascending order.

Build a big pile:

void Swap(HPDataType* p1, HPDataType* p2)
{
    
    
	HPDataType tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}


void AdjustUp(HPDataType* a, int child)
{
    
    
	int parent = (child - 1) / 2;
	//while (parent >= 0)
	while (child > 0)
	{
    
    
		if (a[child] < a[parent])
		{
    
    
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
			//child = (child - 1) / 2;
			//parent = (parent - 1) / 2;
		}
		else
		{
    
    
			break;
		}
	}
}

void AdjustDown(HPDataType* a, int size, int parent)
{
    
    
	int child = parent * 2 + 1;

	while (child < size)
	{
    
    
		// 假设左孩子小,如果解设错了,更新一下

		if (child + 1 < size && a[child + 1] < a[child])
		{
    
    
			++child;
		}

		if (a[child] < a[parent])
		{
    
    
			Swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
    
    
			break;
		}
	}
}

void HeapSort(int* a, int n)
{
    
    
	 //建大堆
	 //O(N*logN)
	for (int i = 1; i < n; i++)
	{
    
    
		AdjustUp(a, i);
	}
	int end = n - 1;
	while (end > 0)
	{
    
    
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

Our end is the subscript of the last element, which is the number of previous elements. We let it exchange with the top element of the heap and adjust it downward. After the adjustment, let end–, that is, the top and subscript of the heap are n- 2 elements are exchanged, adjustments are made, and the operation is repeated until end<=0.

We can also improve and optimize the code we build to have a time complexity of O(N):

void HeapSort(int* a, int n)
{
    
    
	 //建大堆
	 /*O(N)*/
	for (int i = (n - 1 - 1) / 2; i >= 0; --i)
	{
    
    
		AdjustDown(a, n, i);
	}

	int end = n - 1;
	while (end > 0)
	{
    
    
		Swap(&a[0], &a[end]);
		AdjustDown(a, end, 0);
		--end;
	}
}

Because the subscript of our parent node is the subscript of the child node minus 1 and divided by 2, we can directly use the loop to pass the subscript of the parent node, so our method is to start from the bottom parent node Adjust, and finally adjust the parent node with index 0.

Next we will test our code:

int main()
{
    
    
	int a[] = {
    
     4, 6, 2, 1, 5, 8, 2, 9 };

	HeapSort(a, sizeof(a)/sizeof(int));

	for (int i = 0; i < sizeof(a)/sizeof(int); i++)
	{
    
    
		printf("%d ", a[i]);
	}
	printf("\n");

	return 0;
}

Insert image description here

Finally, the sorted heap is successfully printed out. thanks for your support!

Guess you like

Origin blog.csdn.net/Lehjy/article/details/134687363
Recommended