一、介绍
堆排序:一种功能强大的排序,效率高没时间复杂度低,为 N*logN
二、过程讲解
两步骤:
步骤一:利用自身建堆,向下调整法
向下调整法建堆,可以大大节省时间效率,时间复杂度为 N
步骤二:排序,向下调整法。
利用end指向堆尾元素。
通过首元素与尾元素的不断交换位置,并向下调整
可以实现升序、降序排列。
end--,直到end走到根部,完成排序。
void AdjustDown(HPDateType* a, int n, int parent)
{
assert(a);
//建大堆:假设左孩子大
int child = parent * 2 + 1; //先× 2,再 + 1
while (child < n) //n是大小,不是下标
{
//向下调整需要找大孩子
if (child + 1 < n
&& a[child + 1] < a[child])
{
child++; //变成右孩子
}
if (a[child] < a[parent])
{
Swap(&a[child], &a[parent]);
//在循环中,让parent与child不断迭代
parent = child;
child = parent * 2 + 1;
}
else
break;
}
}
建堆:
升序:建大堆
降序:建小堆
三、代码实现
void HeapSort(int* a,int n) //N*logN
{
// 升序 -- 建大堆
// 降序 -- 建小堆
//向下调整法建堆:N
for (int i = (n - 1 - 1) / 2; i >= 0; i--) //i是父亲下标,可以为0!!!
{
AdjustDown(a, n, i); //不管父亲坐标是什么,参数n 要传数组大小(向下遍历遍历完整个数组)。
}
//排序
int end = n - 1; //从倒数第一个开始
while (end > 0) //需要把所有元素都完成排序
{
Swap(&a[0], &a[end]);
AdjustDown(a, end, 0);
end--; //控制条件!!!
}
}
四、代码讲解
//向下调整法建堆:N
for (int i = (n - 1 - 1) / 2; i >= 0; i--) //i是父亲下标,可以为0!!!
{
AdjustDown(a, n, i); //不管父亲坐标是什么,参数n 要传数组大小(向下遍历遍历完整个数组)。
}
首先对数组建堆
//交换位置,向下调整,恢复堆序
//排序
int end = n - 1; //从倒数第一个开始
while (end > 0) //需要把所有元素都完成排序
{
Swap(&a[0], &a[end]);
AdjustDown(a, end, 0);
end--; //控制条件!!!
}