排序算法要点
第一篇: 堆排序
二叉堆满足二个特性:
1).父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。
2).每个结点的左子树和右子树都是一个二叉堆(都是最大堆或最小堆)。
堆排序的三个要点
从小到大排序,要先建立最大堆。
以构建最大堆为例
1.堆调整
以待排序节点开始,遍历子节点,把两个子节点值比较大的子节点向上移动。
两个子节点都比该节点小,说明不用在调节了。注意,要保证这个步骤成立,本次堆调整时,子节点都是二叉堆。
当然了,叶子节点一定是二叉堆(因为没有子节点)。
还要注意一点是,一次调节交换可能会破坏子节点的有序性,所以每次调节都要调整到二叉树叶节点位置(当然,也可以是两个子节点都比该节点小时)。
2.构建堆
构建堆就是构建一个根节点位置开始的二叉堆。所以要先保证它的子节点也是二叉堆。
void MakeMinHeap(int a[], int n)
{
for (int i = n / 2; i > 0; i--)
MinHeapFixdown(a, i, n);
}
注意,构建的二叉堆的数组元素还不是排好顺序的,因为不能保证左子树和右子树的顺序。
3.二叉堆排序
二叉堆的根节点一定是最大的,将它换到数组末尾不再移动,将数据末尾的节点换到根节点,重新调整二叉堆。
重复这个过程,直到数据全部移动到二叉堆的后面。
for (int i = n; i > 1; i--)
{
swap(a[1], a[i]);
MinHeapFixdown(a, 1, i-1);
}