堆排序算法——C/C++

堆排序算法——C/C++堆排序1、算法思想堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。2、实现原理要实现从小到大的排序,就要建立大顶堆,即父节点比子节点都要大。2.1、初始化数组,创建大顶堆。大顶堆的创建从下往上比较,不能直接用无序数组从根节点比较,否则有的不符合大顶堆的定义。…

大家好,又见面了,我是你们的朋友全栈君。

堆排序

1. 算法思想

堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

2. 实现原理

要实现从小到大的排序,就要建立大顶堆,即父节点比子节点都要大。

2.1、初始化数组,创建大顶堆。
	1. 大顶堆的创建从下往上比较,不能直接用无序数组从根节点比较,否则有的不符合大顶堆的定义。
2.2、交换根节点和倒数第一个数据,现在倒数第一个数据就是最大的。
2.3、重新建立大顶堆。
	1. 因为只有 array[0] 改变,其它都符合大顶堆的定义,所以可以根节点 array[0] 重新建立。
2.4、重复2.22.3的步骤,直到只剩根节点 array[0],即 i=1

3. 动态演示

网上这个就展示的非常好
在这里插入图片描述

我再用图片稍微解释一下。
原始数据:array[]={49,38,65,97,76,13,27,49,10}
原始堆排序
在这里插入图片描述创建大顶堆
从倒数第二行往上比较父节点和子节点(即从数据一半开始向前运算),把大的往上移动,小的向下移,直到符合大顶堆定义。
在这里插入图片描述交换根节点和最后一个节点
在这里插入图片描述
重新创建大顶堆
在这里插入图片描述接下来就一直循环即可得到堆排序结果

4. 完整代码

五个函数
交换函数:void swap(int array[],int x,int y)
初始化大顶堆函数:void BuildHeap(int array[],int size)
生成大顶堆函数:void Down(int array[],int i,int n)
排序函数:void heapSort(int array[],int size)
主函数:int main()

#include <stdio.h>
void display(int array[], int size) { 

for (int i = 0; i < size; i++) { 

printf("%d ", array[i]);
}
printf("\n");
}
void swap(int array[], int x, int y) { 

int key  = array[x];
array[x] = array[y];
array[y] = key;
}
// 从大到小排序
// void Down(int array[], int i, int n) { 

// int child = 2 * i + 1;
// int key = array[i];
// while (child < n) { 

// if (child + 1 < n && array[child] > array[child + 1]) { 

// child++;
// }
// if (key > array[child]) { 

// swap(array, i, child);
// i = child;
// } else { 

// break;
// }
// child = child * 2 + 1;
// }
// }
// 从小到大排序
void Down(int array[], int i, int n) { 
 // 最后结果就是大顶堆
int parent = i;                    // 父节点下标
int child  = 2 * i + 1;            // 子节点下标
while (child < n) { 

if (child + 1 < n && array[child] < array[child + 1]) { 
 // 判断子节点那个大,大的与父节点比较
child++;
}
if (array[parent] < array[child]) { 
 // 判断父节点是否小于子节点
swap(array, parent, child);     // 交换父节点和子节点
parent = child;                 // 子节点下标 赋给 父节点下标
}
child = child * 2 + 1; // 换行,比较下面的父节点和子节点
}
}
void BuildHeap(int array[], int size) { 

for (int i = size / 2 - 1; i >= 0; i--) { 
 // 倒数第二排开始, 创建大顶堆,必须从下往上比较
Down(array, i, size);                 // 否则有的不符合大顶堆定义
}
}
void HeapSort(int array[], int size) { 

printf("初始化数组:");
BuildHeap(array, size); // 初始化堆
display(array, size);   // 查看初始化结果
for (int i = size - 1; i > 0; i--) { 

swap(array, 0, i); // 交换顶点和第 i 个数据
// 因为只有array[0]改变,其它都符合大顶堆的定义,所以可以从上往下重新建立
Down(array, 0, i); // 重新建立大顶堆
printf("排序的数组:");
display(array, size);
}
}
int main() { 

int array[] = { 
49, 38, 65, 97, 76, 13, 27, 49, 10};
int size    = sizeof(array) / sizeof(int);
// 打印数据
printf("%d \n", size);
printf("排序前数组:");
display(array, size);
HeapSort(array, size);
return 0;
}

5. 结果展示

(显示每次排序结果)
从小到大
在这里插入图片描述从大到小
在这里插入图片描述

6. 算法分析

时间复杂度:

  1. 最好:O(n log n)
  2. 最坏:O(n log n)
  3. 平均:O(n log n)

空间复杂度:O(1)

稳定性:不稳定

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158124.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • BeanUtils_BeanUtils

    BeanUtils_BeanUtilsBeanUtils类依赖的jar包注意:其中第二个包一定是commons-collections-xxx.jar,之前使用了commons-collectionsx-xxx.jar在web上显示未找到类BeanUtils类当中的主要方法populate(Objectbean,Map<String,?extendsObject>properties):可以将pr…

  • Actuator「建议收藏」

    Actuator「建议收藏」#Actuator引入依赖spring-boot-starter-actuator,通过endpoint来暴露HTTP或JMX来监管应用通过http://localhost:8080/actuat

  • java框架中的controller层、dao层、domain层、service层、view层[通俗易懂]

    1.Controller层:接口层,用户访问请求时对接。Controller层负责具体的业务模块流程的控制,在此层里面要调用Serice层的接口来控制业务流程,控制的配置也同样是在Spring的配置文件里面进行,针对具体的业务流程,会有不同的控制器,我们具体的设计过程中可以将流程进行抽象归纳,设计出可以…

  • 莫烦python教程地址

    莫烦python教程地址https://morvanzhou.github.io/tutorials/

  • windebug调试方法_java怎么远程调试

    windebug调试方法_java怎么远程调试关于WCF的调试,MSDN给出如下说明,可能是由于我的水平问题,个人无法完全看懂,所以自己总结了一点WCF的调试技巧。仅供参考。如何开始调试WCF服务: 通常WCF可以部署成Windowsservice和Webservice。1.对于WebService通常后缀都是*.svc对于这类我通常有2种方式对其调试a.      新建一个控制台程序,通过AddwebR

    2022年10月30日
  • RabbitMQ 原理图和名词理解(二)[通俗易懂]

    RabbitMQ 原理图和名词理解(二)[通俗易懂]一、RabbitMQ简介RabbitMQ是基于AMQP实现的一个开源消息组件,主要用于在分布式系统中存储转发消息,由因高性能、高可用以及高扩展而出名的Erlang写成。其中,AMQP(AdvancedMessageQueuingProtocol,即高级消息队列协议),是一个异步消息传递所使用的应用层协议规范,为面向消息的中间件设计。RabbiMQ是EDA事件驱动架构的核心,也是CQR…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号