堆排序:
堆排序算法流程图:(图解)
![](https://i-blog.csdnimg.cn/blog_migrate/c2b22ef9149569bd8fc195c2a74ecb41.png)
下面是实现流程:
代码实现:
//5.堆排序
void Heap(int a[], int length) {
//两个参数:存放数据的数组,数据长度
//1.建大堆
CreatHeap(); //这里没有写 后面再写
//2.开始排序
for (int i = 0; i < length - 1;i++) {
Swap(&a[0], a + length - i); //交换根节点和最后一个数据
AdjustDown(a,length-1-i,0); //向下调整,保证调整成一直是大堆
}
}
void Swap(int* a, int* b) {
int arr = *a;
*a = *b;
*b = arr;
}
void AdjustDown(int array[], int length,int root) { //核心:向下调整
//三个参数:存放数据的数组,数据长度,要调整的数据
while (1) {
//看root,根节点就是0
//判断root是否是叶子节点
//因为堆是完全二叉树 ,没有左孩子一定没有有孩子
//堆是顺序存储,找到左孩子的下标,如果左孩子下标越界,则没有左孩子
int left = 2 * root + 1; //这个要记住的,这个是固定的 /* 数组从0索引,因此左孩子索引为i * 2 + 1 */
if (left >= length) { //不要漏掉等于
//是叶子结点
return;
}
//找到左右孩子中最小的一个
//这里一定有左孩子,判断是否有右孩子
int right = 2 * root + 2; //这个要记住的,这个是固定的 /* 数组从0索引,因此右孩子索引为i * 2 + 2 */
int min = left;
if (right < length //有右孩子
&&array[right] < array[left]) {
//右孩子值小于左孩子
//&& array[right] > array[left]) //大堆
min = right;
} //比较array[min] array[root]
if (array[min] <= array[root])
//if (array[min] >= array[root]) //大堆
{
return;
}
//交换
int t = array[root];
array[min] = array[root];
array[min] = t;
//继续向下调整,以min作为结点
AdjustDown(array, length, min);
}
}