我们知道数据结构的其实是一种完全二叉树。
今天我了解了建堆算法
一、向上建堆
当我们建堆时,需要不断插入数据。而堆实际的存储方式是一个顺序表。插入数据时,在尾端插入数据。

在一个大堆中,我们需要将需要插入的元素的结点和他的双亲结点比较,如果孩子的值大于父亲结点的值,则孩子结点与父亲结点互换位置,即,孩子向上调整。直到比父亲结点的值小。
它的时间复杂度是:log(n)
void AdjustUp(int* a,int child)
{
assert(a);
int parent = (child-1)/2;
while(child>0)
{
if(a[parent]<a[child]
{
swap(&a[parent],&a[child]);
child = parent;
parent = (child-1)/2;
}
else
break;
}
二、向下调整
当我们要从堆中将元素出堆,我们该怎么处理呢。方法一是,先将最后一个元素和第一个元素互换。然后将顺序表的大小减小。当我们将堆顶元素换到末尾后,那么比较小的元素也被我们换到堆顶了,这时就需要使用 向下调整。

void AdjustDown(int* a,int size,int parent)
{
Swap(&a[0],&a[size-1]);
int child = parent*2+1;
while()
{
if(child+1<n&&a[child+1]>a[child])
{
child++;
}
if(a[parent]<a[child])
{
Swap(&a[child],&a[parent]);
parent = child;
child = parent*2+1;
}
else
break;
}
三、堆排序
我们可以利用堆的性质来排序。其实也就是出堆的相似原理;
当然,我们可以开辟新的空间来存储依次出的堆顶元素。如果我们就只用堆,来排序;
原理是这样:

void HeapSort(int* a,int size)
{
//向上建堆
for(int i = 0;i<size;i++)
{
AdjustUp(a,i);
}
int end = size-1;
while(end>0)
{
Swap(&a[0],&a[end]);
AdjustDown(a,end,0)
end--;
}