堆排序(初阶数据结构)-创新互联
一、堆的基本概念
分享标题:堆排序(初阶数据结构)-创新互联
网站URL:http://azwzsj.com/article/eoeed.html
在空间结构上时一维数组,在逻辑结构上满足“父节点的值均不小于(不大于)子节点”,逻辑结构上 堆是一个完全二叉树。由父节点与子节点的关系,又可以分为大堆和小堆,其中根节点为堆顶。堆顶是大值或者最小值;
专注于为中小企业提供网站设计制作、成都做网站服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业潜江免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千余家企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。二、堆的实现堆实质上是一个数组 所以类顺序表的设计
#include#include#include
#include#includetypedef int HPDataType;
typedef struct Heap
{
HPDataType* _a;
int _size;
int _capacity;
}Heap;
//堆的初始化:
//初始化堆
void Heapinit(Heap*hp)
{
assert(hp);
hp->_a = NULL;
hp->_capacity = hp->_size = 0;
}
以下为了方便 以大堆为例(小堆变换调整符号即可)
接口👇👇//向上调整
void AdjustUp(HPDataType*a, size_t child);
//向下调整
void AdjustDown(HPDataType*a, size_t size);
// 堆的销毁
void HeapDestory(Heap* hp);
// 堆的插入
void HeapPush(Heap* hp, HPDataType x);
// 堆的删除
void HeapPop(Heap* hp);
// 取堆顶的数据
HPDataType HeapTop(Heap* hp);
// 堆的数据个数
int HeapSize(Heap* hp);
// 堆的判空
int HeapEmpty(Heap* hp);
1.堆数据的插入
void HeapPush(Heap* hp, HPDataType x)
{
assert(hp);
if (hp->_capacity<= hp->_size)
{
//开辟一块空间 如果是0;就开辟四个整形的大小,一次扩容两个整形的大小
int newcapacity = hp->_capacity== 0 ? 4 : hp->_capacity * 2;
HPDataType* tmp = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
hp->_a = tmp;
hp->_capacity = newcapacity;
}
hp->_a[hp->_size] = x;
AdjustUp(hp->_a, hp->_size);
hp->_size++;
}
约定成俗 有两个公式://父节点
parent=(child-1)/2;
//子节点
leftchild=parent*2+1;//左孩子
rightchild=parent*2+2;//右孩子
向上调整法://向上调整(即建立大堆时,将大的数向上调整)
//push时复用
void AdjustUp(HPDataType*a , size_t child)
{
assert(a);
while (child != 0)
{
size_t parent = (child - 1) / 2;
if (a[child] >a[parent])
{
//如果子节点大于父节点则需要调整
//将子节点向上调整
Swap(&a[child], &a[parent]);
}
else
{
break;
}
//更新下标
child = parent;
}
}
向下调整法:void AdjustDown(HPDataType*a, size_t size)
{
assert(a);
size_t parent = 0;
size_t child = parent * 2 + 1;
while (child< size)
{
if (child + 1< size && a[child]< a[child + 1])
{//确保child是左右中大的那一个
child++;
}
if (a[parent]< a[child])
{
Swap(&a[parent], &a[child]);
}
else
{
break;
}
//更新下标
//再与后面的子树比较
parent = child;
child = parent * 2 + 1;
}
}
函数的实现当堆中没有存放数据时,一个空堆插入,不同于顺序表的尾插,堆结构需要在插入数据时保持结构成立(父节点大于/小于子节点)
void HeapPush(Heap* hp, HPDataType x)
{
assert(hp);
if (hp->_capacity<= hp->_size)
{
//开辟一块空间 如果是0;就开辟四个整形的大小,一次扩容两个整型的大小
int newcapacity = hp->_capacity== 0 ? 4 : hp->_capacity * 2;
HPDataType* tmp = (HPDataType*)realloc(hp->_a, sizeof(HPDataType) * newcapacity);
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
hp->_a = tmp;
hp->_capacity = newcapacity;
}
hp->_a[hp->_size] = x;
//即插入即排序
AdjustUp(hp->_a, hp->_size);
hp->_size++;
}
函数的删除将根与最后一个叶子交换 size--删除 再将新根向下重新排序
void HeapPop(Heap* hp)
{
assert(hp);
assert(hp->_size >0);
Swap(&hp->_a[0], &hp->_a[hp->_size-1]);
hp->_size--;
AdjustDown(hp->_a, hp->_size);
}
//取顶
HPDataType HeapTop(Heap* hp)
{
assert(hp);
assert(hp->_size >0);
return hp->_a[0];
}
//大小
int HeapSize(Heap* hp)
{
assert(hp);
return hp->_size;
}
调试结果一个堆就实现啦~~有错误欢迎指正
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享标题:堆排序(初阶数据结构)-创新互联
网站URL:http://azwzsj.com/article/eoeed.html