C++堆排序算法的实现
堆排序(Heap sort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序可以用到上一次的排序结果,所以不像其他一般的排序方法一样,每次都要进行n-1次的比较,复杂度为O(nlogn)。
这里先说明以下几个基本概念:
完全二叉树:假设一个二叉树有n层,那么如果第1到n-1层的每个节点都达到最大的个数:2,且第n层的排列是从左往右依次排开的,那么就称其为完全二叉树
堆:本身就是一个完全二叉树,但是需要满足一定条件,当二叉树的每个节点都大于等于它的子节点的时候,称为大顶堆,当二叉树的每个节点都小于它的子节点的时候,称为小顶堆,上图即为小顶堆。
关键的性质:
将堆的内容填入一个一维数组,这样通过下标就能计算出每个结点的父子节点,编号顺序从0开始,从左往右,从上至下层次遍历。a[10] = {2,8,5,10,9,12,7,14,15,13}
若一个结点的下标为k,那么它的父结点为(k-1)/2,其子节点为2k+1和2k+2
例:数字为10的节点的下标为3,父结点为1号:8,子节点为7号和8号:14,15
算法步骤:
1)利用给定数组创建一个堆H[0..n-1](我们这里使用最小堆),输出堆顶元素
2)以最后一个元素代替堆顶,调整成堆,输出堆顶元素
3)把堆的尺寸缩小1
4) 重复步骤2,直到堆的尺寸为1
实现代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <time.h>
#include <Windows.h>
using namespace std;//堆排序的核心是建堆,传入参数为数组,根节点位置,数组长度
void Heap_build(int a[],int root,int length)
{
int lchild = root*+;//根节点的左子结点下标
if (lchild < length)//左子结点下标不能超出数组的长度
{
int flag = lchild;//flag保存左右节点中最大值的下标
int rchild = lchild+;//根节点的右子结点下标
if (rchild < length)//右子结点下标不能超出数组的长度(如果有的话)
{
if (a[rchild] > a[flag])//找出左右子结点中的最大值
{
flag = rchild;
}
}
if (a[root] < a[flag])
{
//交换父结点和比父结点大的最大子节点
swap(a[root],a[flag]);
//从此次最大子节点的那个位置开始递归建堆
Heap_build(a,flag,length);
}
}
} void Heap_sort(int a[],int len)
{
for (int i = len/; i >= ; --i)//从最后一个非叶子节点的父结点开始建堆
{
Heap_build(a,i,len);
} for (int j = len-; j > ; --j)//j表示数组此时的长度,因为len长度已经建过了,从len-1开始
{
swap(a[],a[j]);//交换首尾元素,将最大值交换到数组的最后位置保存
Heap_build(a,,j);//去除最后位置的元素重新建堆,此处j表示数组的长度,最后一个位置下标变为len-2
} }
int main(int argc, char **argv)
{
clock_t Start_time = clock();
int a[] = {,,,,,,,,,};
Heap_sort(a,);
for (size_t i = ; i != ; ++i)
{
cout<<a[i]<<" ";
}
clock_t End_time = clock();
cout<<endl;
cout<<"Total running time is: "<<static_cast<double>(End_time-Start_time)/CLOCKS_PER_SEC*<<" ms"<<endl;
cin.get();
return ;
}
建堆的过程,堆调整的过程,这些过程的时间复杂度,空间复杂度,以及如何应用在海量数据Top K问题中等等,都是需要重点掌握的。
复杂度分析:
最差时间复杂度O(n log n)
最优时间复杂度O(n log n)
平均时间复杂度O(n log n)
最差空间复杂度O(n)
注意:此排序方法不适用于个数少的序列,因为初始构建堆需要时间;
特点分析:不稳定算法(unstable sort)、In-place sort。
---------------------
转载:
作者:MISAYAONE
来源:CSDN
原文:https://blog.csdn.net/misayaaaaa/article/details/65999854
版权声明:本文为博主原创文章,转载请附上博文链接!
有问题欢迎一起讨论!
C++堆排序算法的实现的更多相关文章
- Python八大算法的实现,插入排序、希尔排序、冒泡排序、快速排序、直接选择排序、堆排序、归并排序、基数排序。
Python八大算法的实现,插入排序.希尔排序.冒泡排序.快速排序.直接选择排序.堆排序.归并排序.基数排序. 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得 ...
- Python学习(三) 八大排序算法的实现(下)
本文Python实现了插入排序.基数排序.希尔排序.冒泡排序.高速排序.直接选择排序.堆排序.归并排序的后面四种. 上篇:Python学习(三) 八大排序算法的实现(上) 1.高速排序 描写叙述 通过 ...
- Bug2算法的实现(RobotBASIC环境中仿真)
移动机器人智能的一个重要标志就是自主导航,而实现机器人自主导航有个基本要求--避障.之前简单介绍过Bug避障算法,但仅仅了解大致理论而不亲自动手实现一遍很难有深刻的印象,只能说似懂非懂.我不是天才,不 ...
- Canny边缘检测算法的实现
图像边缘信息主要集中在高频段,通常说图像锐化或检测边缘,实质就是高频滤波.我们知道微分运算是求信号的变化率,具有加强高频分量的作用.在空域运算中来说,对图像的锐化就是计算微分.由于数字图像的离散信号, ...
- java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现
java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...
- SSE图像算法优化系列十三:超高速BoxBlur算法的实现和优化(Opencv的速度的五倍)
在SSE图像算法优化系列五:超高速指数模糊算法的实现和优化(10000*10000在100ms左右实现) 一文中,我曾经说过优化后的ExpBlur比BoxBlur还要快,那个时候我比较的BoxBlur ...
- 详解Linux内核红黑树算法的实现
转自:https://blog.csdn.net/npy_lp/article/details/7420689 内核源码:linux-2.6.38.8.tar.bz2 关于二叉查找树的概念请参考博文& ...
- 详细MATLAB 中BP神经网络算法的实现
MATLAB 中BP神经网络算法的实现 BP神经网络算法提供了一种普遍并且实用的方法从样例中学习值为实数.离散值或者向量的函数,这里就简单介绍一下如何用MATLAB编程实现该算法. 具体步骤 这里 ...
- C++基础代码--20余种数据结构和算法的实现
C++基础代码--20余种数据结构和算法的实现 过年了,闲来无事,翻阅起以前写的代码,无意间找到了大学时写的一套C++工具集,主要是关于数据结构和算法.以及语言层面的工具类.过去好几年了,现在几乎已经 ...
随机推荐
- 架构模式: 客户端 UI 构建
架构模式: 客户端 UI 构建 上下文 您已应用微服务架构模式.服务由业务能力/面向子域的团队开发,这些团队也负责用户体验.一些UI屏幕/页面显示来自多个服务的数据.例如,考虑亚马逊风格的产品详细信息 ...
- 整合AD RMS与EX 2010。
1.点击开始菜单, 选择所有程 序,展开 Mi cros oft Excha nge Server 2010 ,打开Excha nge Ma na gement Cons ol e,选择收件人配 ...
- 【并行计算-CUDA开发】CUDA编程——GPU架构,由sp,sm,thread,block,grid,warp说起
掌握部分硬件知识,有助于程序员编写更好的CUDA程序,提升CUDA程序性能,本文目的是理清sp,sm,thread,block,grid,warp之间的关系.由于作者能力有限,难免有疏漏,恳请读者批评 ...
- 论文阅读 | Probing Neural Network Understanding of Natural Language Arguments
[code&data] [pdf] ARCT 任务是 Habernal 等人在 NACCL 2018 中提出的,即在给定的前提(premise)下,对于某个陈述(claim),相反的两个依据( ...
- 浅谈 OpenResty,基于opebresty+redis进行实时线上限流
一.前言 我们都知道Nginx有很多的特性和好处,但是在Nginx上开发成了一个难题,Nginx模块需要用C开发,而且必须符合一系列复杂的规则,最重要的用C开发模块必须要熟悉Nginx的源代码,使得开 ...
- PTA (Advanced Level)1077.Kuchiguse
The Japanese language is notorious for its sentence ending particles. Personal preference of such pa ...
- 「java.util.concurrent并发包」之 ThreadPoolExecutor
一 异步用new Thread? 大写的"low"!! new Thread(new Runnable() { @Override public void run() { // T ...
- Log4j2配置之Appender详解
Log4j2配置之Appender详解 Appender负责将日志事件传递到其目标.每个Appender都必须实现Appender接口.大多数Appender将扩展AbstractAppender,它 ...
- 后缀数组练习2:可重叠的k次最长重复子串
其实和上一题是差不多的,只是在二分check的时候有一些小小的改动 1468: 后缀数组2:可重叠的k次最长重复子串 poj3261 时间限制: 1 Sec 内存限制: 128 MB提交: 113 ...
- Laravel-admin 消息提醒、播放音频、点击跳转
jquery-toastr 消息提醒.播放音频.点击跳转 应用情景,有新的订单生成,后台进行消息提醒并播放音频(这里用到轮询简单实现):下面附代码 1.找到laravel-admin 中的 index ...