堆排序:升序输出

核心思想:
    要求升序输出,也就是从小到大排列
1.建大堆:
    关键:在于向下调整
2.建好大堆后,循环删除堆顶元素
    关键在于:堆顶元素与最后一个元素进行交换

1.sort.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void Swap(int *a, int *b)
{
    int tmp = *a;
    *a = *b;
    *b = tmp;
    return;
}

void PrintArray(int array[], int size)
{
    printf("打印数组结果:\n");
    int i = 0;
    for (; i < size; ++i) {
        printf("%d ", array[i]);
    }
    printf("\n");
}
/*****************************************************
*   堆排序
*   时间复杂度:O(NlogN)
*   空间复杂度:O(1)
*   稳定性:不稳定排序
******************************************************/
// 建立一个大堆,要求父节点大于左右子树

// 向下调整
// index 表示从当前下标开始进行调整
void AdjustDown(int array[], int size, int index)
{
    int parent = index;
    int child = 2 * parent + 1; // 左子树

    while (child < size) {
        // 先拿左右子树进行比较,看谁比较大,然后再拿大的和父节点进行比较

        if (child + 1 < size && array[child + 1] > array[child]) {
            // 右子树比左子树大,就让 child 指向右子树
            child = child + 1;
        }

        // 此时下标为child的结点是左右子树中最大的,
        // 因此用大的孩子结点和父结点进行比较,若孩子结点大于父节点则进行交换
        if (array[child] > array[parent]) {
            Swap(&array[child], &array[parent]);
        }
        else
        {
            // 此时调整就调整完了
            break;
        }
        // 继续向下调整,直到 child >= size(最后一个结点的下标最大,为 size-1)
        parent = child;
        child = 2 * parent + 1;
    }
}

// 创建大堆: 重点在向下调整
void HeapCreate(int array[], int size)
{
    if (size <= 1) {
        return;
    }
    // 下沉式调整,需要从后往前遍历
    // 从最后一个非叶子结点开始遍历
    // size - 1 表示最后一个元素的下标
    // 拿着这个下标 -  1 / 2 就得到了当前元素的父节点即(size - 1 - 1) / 2
    int i = (size - 1 - 1) / 2;
    for (; i >= 0; --i) {
        AdjustDown(array, size, i);
    }
}

// 堆删:将堆顶元素与最后一个元素交换,然后将元素个数减去一,最后进行向下调整
void HeapPop(int array[], int size) {
    if (size <= 1) {
        return;
    }

    // 关键在于将堆顶元素与最后一个源交换
    // 向下调整时,元素个数 - 1,即相当于删除了一个元素,破坏了堆,要进行调整
    Swap(&array[0], &array[size -1]);
    AdjustDown(array, size - 1, 0);
}

// 堆排序:升序,即从小到大排列
// 建大堆,循环删除堆顶元素
void HeapSort(int array[], int size) 
{
    if (size <= 1) {
        return;
    }

    // 1. 建立大堆
    HeapCreate(array, size);

    // 2. 循环删除堆顶元素,
    // 每删除一个元素,就是将最大的值放在堆尾
    int i = 0;
    for (; i < size; ++i) {
        HeapPop(array, size - i);
    }
}
/*****************************************************
*   以下为测试代码
*****************************************************/
void TestHeapSort()
{
    int array[] = {53, 17, 78, 9, 45, 65, 87, 23, 31};
    int size = sizeof(array) / sizeof(array[0]);
    HeapSort(array, size);
    PrintArray(array, size);
}

2.Main.c

#include "sort.h"

int main()
{
    TestHeapSort();

    system("pause");
    return 0;
}

3.截图
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39026129/article/details/81368664