C++实现堆排序实例介绍
作者:NEU! 发布时间:2022-06-05 12:33:54
标签:C++,堆排序
概述:
堆排序是利用构建“堆”的方法确定具有最大值的数据元素,并把该元素与最后位置上的元素交换。可将任意一个由n个数据元素构成的序列按照(a1,a2,...,an),按照从左到右的顺序按层排列构成一棵与该序列对应的完全二叉树。
一棵完全二叉树是一个堆,当且仅当完全二叉树的每棵子树的根值ai≥其左子树的根值a2i,同时ai≥其右子树的根值a 2i+1 (1<i<n/2)。
实现堆排序需要实现两个问题:
如何由无序序列建成一个堆?如何在输出堆顶元素之后,调整剩余元素成为一个新的堆?
思路:
堆排序算法思想:1、从最后一个非叶子节点逐步到树根,对每个子树进行调整堆。
2、重复n-1次如下处理:将堆的根与最后一个叶子交换,除最后一个叶子之外剩余部分再调整为堆。
调整堆算法思想:1、将树根与其左右子树根值最大者交换;(大顶堆)
2、对交换后的左(或右)子树重复过程1,直到左(或右)子树为堆。
时间复杂度:O(nlogn)
代码:
调整堆算法:
void HeapAdjust(int *array,int i,int length){//调整堆
int leftChild=2*i+1;//定义左右孩子
int rightChild=2*i+2;
int max=i;//初始化,假设左右孩子的双亲节点就是最大值
if(leftChild<length&&array[leftChild]>array[max]){
max=leftChild;
}
if(rightChild<length&&array[rightChild]>array[max]){
max=rightChild;
}
if(max!=i){//若最大值不是双亲节点,则交换值
swap(array[max],array[i]);
HeapAdjust(array,max,length);//递归,使其子树也为堆
}
}
堆排序算法:
void HeapSort(int *array,int length){//堆排序
for(int i=length/2-1;i>=0;i--){//从最后一个非叶子节点开始向上遍历,建立堆
HeapAdjust(array,i,length);
}
for(int j=length-1;j>0;j--){//调整堆 ,此处不需要j=0
swap(array[0],array[j]);
HeapAdjust(array,0,j);//因为每交换一次之后,就把最大值拿出(不再参与调整堆),第三个参数应该写j而不是length
Print(array,length);
}
}
完整代码:
//堆排序
#include <iostream>
using namespace std;
void Print(int array[],int length){//每执行一次打印一次序列
for(int i=0;i<length;i++){
cout<<array[i]<<" ";
}
cout<<endl;
}
void HeapAdjust(int *array,int i,int length){//调整堆
int leftChild=2*i+1;//定义左右孩子
int rightChild=2*i+2;
int max=i;//初始化,假设左右孩子的双亲节点就是最大值
if(leftChild<length&&array[leftChild]>array[max]){
max=leftChild;
}
if(rightChild<length&&array[rightChild]>array[max]){
max=rightChild;
}
if(max!=i){//若最大值不是双亲节点,则交换值
swap(array[max],array[i]);
HeapAdjust(array,max,length);//递归,使其子树也为堆
}
}
void HeapSort(int *array,int length){//堆排序
for(int i=length/2-1;i>=0;i--){//从最后一个非叶子节点开始向上遍历,建立堆
HeapAdjust(array,i,length);
}
for(int j=length-1;j>0;j--){//调整堆 ,此处不需要j=0
swap(array[0],array[j]);
HeapAdjust(array,0,j);//因为每交换一次之后,就把最大值拿出(不再参与调整堆),第三个参数应该写j而不是length
Print(array,length);
}
}
int main(){
int array[]={49,38,65,97,76,13,27,49};
int length=sizeof(array)/sizeof(*array);
Print(array,length);//先打印原始序列
HeapSort(array,length);
return 0;
}
运行示例:
第一行是原始序列,第二到八行分别是经过7次调整堆所得到的序列。
来源:https://blog.csdn.net/weixin_59566851/article/details/122075594


猜你喜欢
- 本文实例为大家分享了Android实现双曲线折线图的具体代码,供大家参考,具体内容如下先看一下效果图1.先下载jar包 mpandroidc
- Android获取分享应用列表详解及实例如果在应用的AndroidManifest.xml中含有 ACTION_SEND 属性,那就证明该应
- 多线程可以说是面试官最喜欢拿来问的题目之一了,可谓是老生之常谈,不管你是新手还是老司机,我相信你一定会在面试过程中遇到过有关多线程的一些问题
- 本文实例为大家分享了Androidstudio调用摄像头拍照并保存照片的具体代码,供大家参考,具体内容如下首先在manifest.xmlns
- 概念 基本映射是对一个实体进行映射,关联映射就是处理多个实体之间的关
- 1. AIE (演示地址)AIE是一个开源的ajax图片编辑器,基于ExtJS与PHP ImageMagick开发,易于与博客/相册等其它应
- 前几天在琢磨mybatis xml热加载的问题,原理还是通过定时扫描xml文件去跟新,但放到项目上就各种问题,由于用了mybatisplus
- 1. 使用方法首先从http://repo1.maven.org/maven2/com/alibaba/druid/&
- try就像一个网,把try{}里面的代码所抛出的异常都网住,然后把异常交给catch{}里面的代码去处理。最后执行finally之中的代码。
- 废话不多说,直接上代码/// <summary> /// 获得当前绝对路径
- 数据适配DataAdapter 对象是DataSet 和数据源之间的桥梁,可以建立并初始化数据表(即DataTable),对数据源执行SQL
- POM:<dependency> <groupId>com.baomidou</groupId&g
- 本章先讲解Java随机数的几种产生方式,然后通过示例对其进行演示。广义上讲,Java中的随机数的有三种产生方式:(01). 通过System
- 上一篇JavaMail入门第四篇 接收邮件中,控制台打印出的内容,我们无法阅读,其实,让我们自己来解析一封复杂的邮件是很不容易的,邮件里面格
- 本文实例为大家分享了Android表格布局TableLayout的具体代码,供大家参考,具体内容如下1.TableLayout TableL
- 前言今天起床,拿起手机开机第一时间当然是打开微信了,左右滑动Viewpager,发现它使用了一种叫惰性加载,或者说懒加载(lazy-load
- 本文实例为大家分享了Android读取手机通讯录联系人到项目的具体代码,供大家参考,具体内容如下一、主界面代码如下:<LinearLa
- 本实例主要实现下面三个基本功能1、C#开发windows服务2、禁止QQ等程序运行3、为windows服务创建自动安装程序下面针对这三个基本
- 为哪些方法代理?实现自己 * ,首先需要关注的点就是,代理对象需要为哪些方法代理? 原生JDK的 * 的实现是往上抽象出一层接口,让目标
- C#是托管型代码,创建的对象会自动回收。C++是非托管型代码,创建的对象需要手动回收(有时不手动回收,可能出现内存溢出的问题)。C#调用C+