【算法导论】手动实现堆

本文介绍了堆数据结构,特别是最大堆,并手动实现了堆的类定义、维护堆性质的MAX_HEAPIFY函数、建堆过程及堆排序算法。堆排序通过调整堆以确保每次取出的都是最大元素,从而实现排序。所有代码参照《算法导论》并在github上提供。
摘要由CSDN通过智能技术生成

A. 堆的简介

堆是一个很好用的数据结构,它既没有搜索二叉树那样严格(要求左子结点必须小于父结点,而右子结点必须不小于左子结点),同时也可以毫不费力气地维护平衡的高度(实现过平衡二叉树的就知道,挺麻烦的)。

堆可以按照它的性质分为最大堆(任意父结点不小于左右子结点)和最小堆(任意父结点不大于左右子结点),两种原理都是一样的,下面就最大堆来讨论。

首先是堆的底层数据的结构,只用到了一个普通的数组!!!没错,没有眼花,就是这样而已,不需要任何指针,简单直观的下标访问——假设父结点的下标为i,那么它的子结点下标分别是:2i(左),2i + 1(右);那么反过来,已知某节点的下标为x,那么它的父结点的下标就是x/2,不管它是左还是右。注意到这里的运算都是跟2的乘法或除法,所以可以用位移运算来加快速度(取下标的操作是很频繁的,积少成多),比如:

size_t Heap::Parent(size_t i) {
    return i >> 1;
}


size_t Heap::Left(size_t i) {
    return i << 1;
}


size_t Heap::Right(size_t i) {
    return (i << 1) + 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值