本文介绍: 1.首先将待排序数组建为大堆,此时堆顶元素就为数组最大值了2.交换堆顶和堆尾元素,此时最大元素就到了堆尾,目前数组最大元素就排好了,现在就假设堆里没有当前这个最大元素了,堆头下面的左右子树仍然是大堆,只需要再将堆顶元素向下调整到合适位置,剩下的n-1个元素还是大堆3.堆头堆尾交换,向下调整,如此反复就可排序。
一:前言
在[C/C++]数据结构 堆的详解中,介绍了什么是堆,并且完成了堆的实现和一系列接口,包括向上调整法和向下调整法等,接下来小编介绍一个有点量级的排序方法——堆排序,时间复杂度为O(n*lgn)
二:堆排序详解
2.1 方法介绍
2.交换堆顶和堆尾元素,此时最大元素就到了堆尾,目前数组最大元素就排好了,现在就假设堆里没有当前这个最大元素了,堆头下面的左右子树仍然是大堆,只需要再将堆顶元素向下调整到合适位置,剩下的n-1个元素还是大堆
3.堆头堆尾交换,向下调整,如此反复就可排序
假设数组第一个元素是堆,再把第二个元素插入,向上调整为堆,插入第三个元素时,前两个是堆,向上调整,插入第四个元素时,前三个元素是堆,以此反复就可以把所有元素建为堆
//建堆
for (int i = 1; i < size; i++)
{
AdjustUp(a, i);
}
2.2 排序
假设我们的待排序数组为:
过程如下:
处理最大元素:
先将堆头元素和堆尾元素交换
处理次大元素:
再次堆头堆尾交换
堆头堆尾交换
处理第N大元素:
……………………
代码实现:
#include<stdio.h>
typedef int HeapDataType;
void swap(HeapDataType* a, HeapDataType* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
//大堆
void AdjustUp(HeapDataType* a, int child)
{
int parent = (child - 1) / 2;
while (child>0)
{
if (a[parent] < a[child])
{
swap(&a[parent], &a[child]);
child = parent;
parent = (parent - 1) / 2;
}
else
{
break;
}
}
}
//大堆
void AdjustDown(HeapDataType* a, int size, int parent)
{
int child = parent * 2 + 1;
while (child<size)
{
//找较大的孩子
if (a[child + 1] > a[child] && child+1<size)
{
child = child + 1;
}
if (a[parent] < a[child])
{
swap(&a[parent], &a[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(HeapDataType* a, int size)
{
//建堆
for (int i = 1; i < size; i++)
{
AdjustUp(a, i);
}
//排序:升序
int end = size - 1;
while (end>0)
{
swap(&a[0], &a[end]);
AdjustDown(a, end, 0); //end指最后一个元素,同时end的值为前面元素的个数
end--;
}
}
测试:
int main()
{
int a[] = { 9,8,6,5,4,2,2,1 };
HeapSort(a, sizeof(a) / sizeof(a[0]));
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++)
{
printf("%d ", a[i]);
}
return 0;
}
原文地址:https://blog.csdn.net/m0_74910646/article/details/134638569
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_39404.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。