堆排序
堆
要了解堆排序,首先要了解堆的一些性质
逻辑结构:完全二叉树 物理结构:数组
父亲的下标是i 左孩子:2i+1 右孩子:2i+2
孩子的下标是i 父亲的下标:(i-1)/2
树中所有父亲大于等于孩子-----大堆
树中所有父亲小于等于孩子-----小堆
一、堆的创建
数组建堆:主要依赖向下调整算法
小堆向下调整算法要求:调整的树的左右子树都是小堆
大堆向下调整算法要求:调整的树的左右子树都是大堆
二、具体实现
1.堆的结构体
代码如下(示例):
typedef struct Heap
{
HPDataType* _a;
int _size;
int _capacity;
}Heap;
2.向下调整算法
代码如下(示例):
void AdjustDown(int* a,int n,int root)
{
int parent=root;
int child=parent*2+1;
while(child<n)
{
if(child+1<n&&a[child+1]<a[child])
{
++child;
}
if(a[child]<a[parent])
{
swap(&a[child],&a[parent]);
parent=child;
child=parent*2+1;
}
else
{
break;
}
}
}
3.堆排序算法
排降序:建小堆 --------将堆排序成降序,建成小堆,最小的永远在根节点,每次把最后一个与根节点互换(根节点放最小的,下一个放在n-1),这样就保证了从底向上,由大到小降序。
也可以使用排升序------建大堆的方法实现。
时间复杂度均为O(NlogN)。
StackSort(int * a,int n)
{
for(int i=(n-1-1)/2;i>=0;--i)
{
AdjustDown(a,n,i);
}
int end=n-1;
while(end>0)
{
Swap(&a[0],&a[end]);
//再继续选次小的
AdjustDown(a,end);
--end;
}
}