当前位置: 首页 > 编程日记 > 正文

白话经典算法系列之七 堆与堆排序

 堆排序高速排序归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法。学习堆排序前,先解说下什么是数据结构中的二叉堆。

二叉堆的定义

二叉堆是全然二叉树或者是近似全然二叉树。

二叉堆满足二个特性:

1.父结点的键值总是大于或等于(小于或等于)不论什么一个子节点的键值。

2.每一个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。

当父结点的键值总是大于或等于不论什么一个子节点的键值时为最大堆。当父结点的键值总是小于或等于不论什么一个子节点的键值时为最小堆。下图展示一个最小堆:

因为其他几种堆(二项式堆,斐波纳契堆等)用的较少,一般将二叉堆就简称为堆。

堆的存储

一般都用数组来表示堆,i结点的父结点下标就为(i – 1) / 2。它的左右子结点下标分别为2 * i + 1和2 * i + 2。如第0个结点左右子结点下标分别为1和2。

堆的操作——插入删除

以下先给出《数据结构C++语言描写叙述》中最小堆的建立插入删除的图解,再给出本人的实现代码,最好是先看明确图后再去看代码。

堆的插入

每次插入都是将新数据放在数组最后。能够发现从这个新数据的父结点到根结点必定为一个有序的数列,如今的任务是将这个新数据插入到这个有序数据中——这就相似于直接插入排序中将一个数据并入到有序区间中,对比《白话经典算法系列之二 直接插入排序的三种实现》不难写出插入一个新数据时堆的调整代码:

//  新添�i结点  其父结点为(i - 1) / 2
void MinHeapFixup(int a[], int i)
{int j, temp;temp = a[i];j = (i - 1) / 2;      //父结点while (j >= 0 && i != 0){if (a[j] <= temp)break;a[i] = a[j];     //把较大的子结点往下移动,替换它的子结点i = j;j = (i - 1) / 2;}a[i] = temp;
}

更简短的表达为:

void MinHeapFixup(int a[], int i)
{for (int j = (i - 1) / 2; (j >= 0 && i != 0)&& a[i] > a[j]; i = j, j = (i - 1) / 2)Swap(a[i], a[j]);
}

插入时:

//在最小堆中添�新的数据nNum
void MinHeapAddNumber(int a[], int n, int nNum)
{a[n] = nNum;MinHeapFixup(a, n);
}

堆的删除

按定义,堆中每次都仅仅能删除第0个数据。为了便于重建堆,实际的操作是将最后一个数据的值赋给根结点,然后再从根结点開始进行一次从上向下的调整。调整时先在左右儿子结点中找最小的,假设父结点比这个最小的子结点还小说明不须要调整了,反之将父结点和它交换后再考虑后面的结点。相当于从根结点将一个数据的“下沉”过程。以下给出代码:

//  从i节点開始调整,n为节点总数 从0開始计算 i节点的子节点为 2*i+1, 2*i+2
void MinHeapFixdown(int a[], int i, int n)
{int j, temp;temp = a[i];j = 2 * i + 1;while (j < n){if (j + 1 < n && a[j + 1] < a[j]) //在左右孩子中找最小的j++;if (a[j] >= temp)break;a[i] = a[j];     //把较小的子结点往上移动,替换它的父结点i = j;j = 2 * i + 1;}a[i] = temp;
}
//在最小堆中删除数
void MinHeapDeleteNumber(int a[], int n)
{Swap(a[0], a[n - 1]);MinHeapFixdown(a, 0, n - 1);
}

堆化数组

有了堆的插入和删除后,再考虑下怎样对一个数据进行堆化操作。要一个一个的从数组中取出数据来建立堆吧,不用!先看一个数组,例如以下图:

非常明显,对叶子结点来说,能够觉得它已经是一个合法的堆了即20,60, 65, 4, 49都各自是一个合法的堆。仅仅要从A[4]=50開始向下调整就能够了。然后再取A[3]=30,A[2] = 17,A[1] = 12,A[0] = 9分别作一次向下调整操作就能够了。下图展示了这些步骤:

写出堆化数组的代码:

//建立最小堆
void MakeMinHeap(int a[], int n)
{for (int i = n / 2 - 1; i >= 0; i--)MinHeapFixdown(a, i, n);
}


至此,堆的操作就所有完毕了(注1),再来看下怎样用堆这种数据结构来进行排序。

堆排序

首先能够看到堆建好之后堆中第0个数据是堆中最小的数据。取出这个数据再运行下堆的删除操作。这样堆中第0个数据又是堆中最小的数据,反复上述步骤直至堆中仅仅有一个数据时就直接取出这个数据。

因为堆也是用数组模拟的,故堆化数组后,第一次将A[0]与A[n - 1]交换,再对A[0…n-2]又一次恢复堆。第二次将A[0]与A[n – 2]交换,再对A[0…n - 3]又一次恢复堆,反复这种操作直到A[0]与A[1]交换。因为每次都是将最小的数据并入到后面的有序区间,故操作完毕后整个数组就有序了。有点相似于直接选择排序

void MinheapsortTodescendarray(int a[], int n)
{for (int i = n - 1; i >= 1; i--){Swap(a[i], a[0]);MinHeapFixdown(a, 0, i);}
}

注意使用最小堆排序后是递减数组,要得到递增数组,能够使用最大堆。

因为每次又一次恢复堆的时间复杂度为O(logN),共N - 1次又一次恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)。STL也实现了堆的相关函数,能够參阅《STL系列之四 heap 堆》。

注1 作为一个数据结构,最好用类将其数据和方法封装起来,这样即便于操作,也便于理解。此外,除了堆排序要使用堆,另外还有非常多场合能够使用堆来方便和高效的处理数据,以后会一一介绍。

 

 

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/6709644

相关文章:

.NET2.0抓取网页全部链接【月儿原创】

.NET2.0抓取网页全部链接 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.4.18 该方法经过对各大门户网站测试结果是抓取率100%&#xff01; 效果图 后台代码&#xff1a; using System;using System.Data;…

腾讯会议又一黑科技,屏蔽超过 200 种会议噪声是如何做到的?

作者 | 伍杏玲出品 | AI 科技大本营&#xff08;ID:rgznai100&#xff09;远程会议已成为我们常规的工作沟通方式&#xff0c;在线交流打破时间、空间的限制&#xff0c;给予我们便利之际&#xff0c;也屡遭尴尬&#xff1a;忘记静音&#xff0c;一边听会一边敲键盘&#xff0c…

zabbix之日志文件监控

一、日志item介绍 下面介绍zabbix另一个“重量级”的功能——日志文件监控&#xff0c;它最主要的是监控日志文件中有没有某个字符串的表达式&#xff0c;对应日志轮转与否&#xff0c;zabbix都支持。 在配置Item的时候&#xff0c;Type选择Zabbix agent (active)&#xff…

深度学习三巨头共同发文,聊聊深度学习的过去、现在与未来

作者|Yoshua Bengio,Yann LeCun,Geoffrey Hinton译者|香槟超新星出品|AI科技大本营(ID:rgznai100)人工神经网络领域的研究是基于对人类智能的观察而来&#xff1a;人类智能从高度并行的网络中产生&#xff0c;这些网络由结构相对简单的非线性神经元组成&#xff0c;通过调整连接…

ASP.NET2.0图片格式转换【月儿原创】

ASP.NET2.0图片格式转换 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.4.20 说明&#xff1a;本文实现了图片格式随意转换&#xff08;下拉框选择&#xff09;&#xff1b;点击FileUpload立即显示图片&#xf…

org.apache.hadoop.fs-ChecksumException

当ChecksumFileSystem出现问题时抛出 1 package org.apache.hadoop.fs;2 3 import java.io.IOException;4 5 /** Thrown for checksum errors. */6 public class ChecksumException extends IOException {7 private long pos;8 public ChecksumException(String descriptio…

Linux下显示硬盘空间的两个命令

1.df -h &#xff0c;用于显示目前所有文件系统的可用空间及使用情况&#xff0c;示例如下&#xff1a; [rootmsg45 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/vg_msg45-lv_root 50G 15G 33G 31% / tmpfs …

C#对Microsoft.VisualBasic My对象兰台妙选【月儿原创】

C#对Microsoft.VisualBasic My对象兰台妙选 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.4.24 1.添加引用 2.引用Microsoft.VisualBasic 命名空间 3.所有的My对象应用皆出自以下类库&#xff0c;本文仅抛砖…

AIoT的发展路上,英特尔如何通过边缘计算掀起产业变革

你知道吗&#xff1f;到明年&#xff0c;仅我国的物联网连接规模将达到70亿&#xff0c;而全世界的人口也不过刚刚达到这个数字。物联网的爆发意味着什么&#xff1f;相信每个人都有着不同的答案&#xff0c;对于我国的14亿人口而言&#xff0c;即将全面到来的物联网红利不仅能…

Xbox One 游戏欣赏: Xbox Fitness 太极拳游戏

早就听说Xbox One中带有太极拳&#xff0c;这是我一直想练的&#xff0c;终于找到“死人定制”的师傅了。因为看书很难练&#xff0c;找不到联系场所&#xff0c;要么就要花价格不菲的学费。Xbox 360中的型可塑2012游戏中&#xff0c;包含了一个游戏章节就是Taiji&#xff0c;但…

Android美工坊:Selector选择器的使用

Android selector选择器可以让你切换自定义的背景风格&#xff0c;比如button、ListView、或者布局点击时候的背景切换等&#xff0c;都需要用到它 背景可以是自定义到颜色&#xff0c;或者图片资源 首先需要在你的res目录下创建drawable文件夹&#xff0c;然后在里面创建一个s…

C#中判断空字符串的3种方法性能分析【月儿原创】

C#中判断空字符串的3种方法性能分析 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.4.28 3种方法分别是&#xff1a;string a"";1.if(a"")2.if(aString.Empty)3.if(a.Length0) 3种方法都是…

微软职位内部推荐-SDEII

微软近期Open的职位:Title: Software Development Engineer 2Group: Bing Client, Search Technology Center Asia, BingWork Location: Beijing/Suzhou, China Group OverviewSearch Technology Center Asia (STCA)STCA was founded in year 2005 and is now starting the sec…

WAIC剪影:AI的未来,关乎星辰大海

“天文学&#xff0c;是像数学一样的基础学科&#xff0c;而越是基础学科&#xff0c;就越难直接应用。”“我们没有想过盈利&#xff0c;这些技术目前来看也不太可能直接应用到其他领域。”“不管是优图还是腾讯公司层面&#xff0c;不是做的每件事情都要考虑它的经济价值或者…

用Swift实现一款天气预报APP(三)

这个系列的目录&#xff1a; 用Swift实现一款天气预报APP&#xff08;一&#xff09; 用Swift实现一款天气预报APP&#xff08;二&#xff09; 用Swift实现一款天气预报APP&#xff08;三&#xff09; 通过前面的学习&#xff0c;一个天气预报的APP已经基本可用了。至少可以查看…

asp.net2.0学习历程 菜鸟到中级程序员的飞跃【月儿原创】

asp.net2.0学习历程 菜鸟到中级程序员的飞跃 --30本好书点评 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.5.16 学历历程 如果你是一个菜鸟或者自认为初学者那么本文非常适合你&#xff1b; 不能说这30本书…

了解黑客的关键工具---揭开Shellcode的神秘面纱

2019独角兽企业重金招聘Python工程师标准>>> ref: http://zhaisj.blog.51cto.com/219066/61428/ 了解黑客的关键工具---揭开Shellcode的神秘面纱 对于初期接触网络安全的人来说&#xff0c;Shellcode是很神秘的东西&#xff0c;对于网络攻击过程中的嗅探信息、漏洞…

2021年移动云API应用创新开发大赛火热开启!

每一位开发者&#xff0c;都是这个时代宝贵的财富2021年移动云API应用创新开发大赛以“创新云转型&#xff0c;智慧云服务”为主题旨在激发开发者创新动力丰富云计算应用场景与移动云携手探索数智未来给社会带来更多智慧创新体验大赛官方报名通道已开启您可通过下方二维码报名参…

Android 多媒体综述

Android 多媒体综述 多媒体系统是Android中最为庞大的系统&#xff0c;涉及了硬件抽象层、编解码、OpenCore多媒体框架、Android多媒体框架、Java层接口多方面的内容。一、引言本系列内容都是在Android应用层面的&#xff0c;将会分为Camera、Audio、Video三部分进行讲述。另外…

asp.net2.0导出pdf文件完美解决方案【月儿原创】

asp.net2.0导出pdf文件完美解决方案 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.5.28 PDF简介&#xff1a;PDF&#xff08;Portable Document Format&#xff09;文件格式是Adobe公司开发的电子文件格式。这…

MYSQL 部分事务

MYSQL 中通过 savepoint 的方式来实现只提交事务的一部分。 step 1 : savepoint savepoint_name;、 做标记 step 2 :rollbak to savepoint savepoint_name;回滚到标记点 setp 3 :release savepoint savepoint_name;解除标记 -------------------------------------------------…

二维已经 OUT 了?3DPose 实现三维人体姿态识别真香 | 代码干货

作者|李秋键出品|AI科技大本营(ID:rgznai100)引言人体姿态估计是计算机视觉领域很多研究工作的基础&#xff0c;也是研究的热点问题&#xff0c;在行为识别、人机交互、姿态跟踪等领域有着广泛的应用前景。按照人体姿态维度的差异&#xff0c;可以将人体姿态估计任务分为二维人…

python学习------tab补全

python学习------tab补全 python也可以进行tab键补全 123456789101112131415161718#!/usr/bin/env python# -*- coding: utf-8 -*-# python startup fileimport sys import readline import rlcompleter import atexit import os # tab completionreadline.parse_and_bind(tab:…

asp.net的Ajax学习进阶

asp.net的Ajax学习进阶 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.6.3 1.什么是Ajax? 2006年忽如一夜春风来&#xff0c;众多涉及到Web开发的站点都在谈Ajax&#xff0c;那么到底什么是Ajax呢&#xff1f…

Windows下FFmpeg高速入门

本系列文章导航 Windows下FFmpeg高速入门 ffmpeg參数解释 mencoder和ffmpeg參数具体解释&#xff08;Java处理视频&#xff09; Java 生成视频缩略图(ffmpeg) 使用ffmpeg进行视频文件转换成FLV整理 java 视频处理 mencoder java 视频处理 ffmpedmencoder Windows下FFmpeg高速入…

“香山”处理器产生背后的逻辑

作者 | 老石谈芯的老石来源 | 老石谈芯在最近召开的RISC-V中国峰会上&#xff0c;中科院计算所的包云岗研究员团队正式发布了名为“香山”的开源高性能RISC-V处理器。前不久我有幸和包老师就这个事情做了一次深度的交流&#xff0c;我们聊了关于RISC-V、还有“香山”处理器的前…

第79天:jQuery事件总结(二)

上一篇讲到jQuery中的事件&#xff0c;深入学习了加载DOM和事件绑定的相关知识&#xff0c;这篇主要深入讨论jQuery事件中的合成事件、事件冒泡和事件移除等内容。 一、合成事件 jQuery有两个合成事件——hover()方法和toggle()方法&#xff0c;同ready()方法一样&#xff0c;这…

asp.net利用RAR实现文件压缩解压缩【月儿原创】

asp.net利用RAR实现文件压缩解压缩 作者&#xff1a;清清月儿 主页&#xff1a;http://blog.csdn.net/21aspnet/ 时间&#xff1a;2007.6.13 如果服务器上安装了RAR程序&#xff0c;那么asp.net可以调用RAR实现文件压缩与解压缩。 不过要注意的是&#xff0c;由…

缺少HTML Doctype造成的样式问题

很简单的一个登陆界面: 代码&#xff1a; <html> <head><style type"text/css">form span {display: block;font-size: 1em;color: #787878;padding-bottom: 5px;font-weight: 600;font-family: Open Sans, sans-serif; }body{background-color: #…

快收藏!整理了 100 个 Python 小技巧

作者&#xff1a;小F来源&#xff1a; 法纳斯特目前Python可以说是非常流行&#xff0c;在目前的编程语言中&#xff0c;Python的抽象程度是最高的&#xff0c;是最接近自然语言的&#xff0c;很容易上手。你可以用它来完成很多任务&#xff0c;比如数据科学、机器学习、Web开发…