【排序算法】----详解堆排序算法

1.堆排序算法

(1).原理
堆排序是一种选择排序,通过实现大小堆,来取出堆顶的数据,然后和最后一个交换,然后将堆的大小减一,循环这个过程直到,只有一个数据时停止。
升序建大堆,降序建小堆。
(2).问题:很多人会疑惑为什么要交换之后再减小堆的大小呢?难道不交换就不能筛选出我们要的极值吗?
在这里插入图片描述
首先向下调整算法的时间复杂度为O(log n )
数据一共是n个
在这里插入图片描述
先交换再减小,堆的结构变化不大,我们只需要执行一次向下调整算法,就可以重新建堆。
在这里插入图片描述
而直接取出堆顶的数据之后,堆的结构发生改变,重新建立堆的成本太大。

2.代码展示

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

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

//向下调整算法用于建堆
void AdjustDown(int* arr, int parent,int n)
{	
	assert(arr);
	int child = 2 * parent + 1;
	while (child<n)
	{
		if (child+1<n && arr[child] < arr[child + 1])
		{
			++child;
		}
		if(arr[parent] < arr[child])
		{
			Swap(&arr[parent], &arr[child]);
			parent = child;
			child = 2*parent+ 1;
		}
		else
		{
			break;
		}
	}
}
void HeapSort(int* arr, int n)
{
	assert(arr);
	for (int i = (n-2)/2; i >= 0; --i)
	{
		AdjustDown(arr, i, n);
	}
	int end = n-1;
	while (end)
	{
		Swap(&arr[0], &arr[end]);
		--end;
		AdjustDown(arr, 0, end);
	}
}
void Print(int* arr, int n)
{
	for (int i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()
{
	int arr[] = { 1,5,6,7,8,9,64,2,5,6,5,1,3,13,13,1,5,5,15 };
	int n = sizeof(arr) / sizeof(arr[0]);
	HeapSort(arr, n);
	Print(arr, n);
	system("pause");
	return 0;
}

3.结果展示

在这里插入图片描述

4.复杂度分析

堆排序的时间复杂度为O(nlogn)
空间复杂度为O(1)
有兴趣可以去看看堆的实现

发布了79 篇原创文章 · 获赞 6 · 访问量 3773

猜你喜欢

转载自blog.csdn.net/qq_41152046/article/details/105125536
今日推荐