本文介绍: 堆排序,顾名思义是一个利用堆来完成排序的一个操作。在之前,小编在[C语言学习系列–>【关于qsort函数的详解以及它的模拟实现】]谈到冒泡排序,但是冒泡排序的时间复杂度(O(n2))着实有点高,堆排序的时间复杂度相对低很多,O(log2N)。
前言
堆排序,顾名思义是一个利用堆来完成排序的一个操作。在之前,小编在[C语言学习系列–>【关于qsort函数的详解以及它的模拟实现】] 谈到冒泡排序,但是冒泡排序的时间复杂度(O(n2))着实有点高,堆排序的时间复杂度相对低很多,O(log2N)。
堆排序的实现(升序为例)
堆排序不需要我们手搓一个堆的数据结构,因为我们本质上还是在数组上进行操作
堆排序的思想是:
对于大堆、小堆要有清楚的理解,不知道的可以查看小编博客–>堆的实现(C语言版)
结论:升序建大堆,降序建小堆
分析:
假设建小堆:0,3,1,5,4,2,9,7,8,6
虽然把最小的元素取出来了,但是一旦把最小元素拿出来,那么剩下的元素又需要重新建堆,这样时间复杂度会提高,缺陷较大。
假设建大堆:9,8,6,7,3,1,2,4,5,0
第二步:除了最大的那一个数,对剩下的数进行向下调整算法,得到堆顶是剩下数中的最大元素,然后再和剩下元素=中的最后一个元素进行交换,依次执行
代码
# define _CRT_SECURE_NO_WARNINGS
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 + 1] > arr[child])
{
child++;
}
if (arr[child] > arr[parent])
{
Swap(&arr[child], &arr[parent]);
parent = child;
child = 2 * parent + 1;
}
else
break;
}
}
void Heapsort(int* arr, int n)
{
assert(arr);
int i = 0;
for (i = (n - 2) / 2; i >= 0; i--) //建堆
{
AdjustDown(arr, i, n);
}
int end = n - 1;
while (end)
{
Swap(&arr[0], &arr[end]);
AdjustDown(arr, 0, end);
end--;
}
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("n");
}
原文地址:https://blog.csdn.net/weixin_73397765/article/details/134653936
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_3076.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。