1. Heap.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef int(*Compare)(int x, int y);

// call back
int Greater(int x, int y);
int Less(int x, int y);

typedef struct Heap {
    int* arr;
    int capacity;
    int size;
    Compare compare;
} Heap;

void Swap(int* x, int* y);

void AdjustDown(Heap* pH, int root);

void HeapInit(Heap* pH, int* arr, int size, Compare com);

void HeapDestroy(Heap* pH);

void CheckCapacity(Heap* pH);

void AdjustUp(Heap* pH, int index);

void HeapInsert(Heap* pH, int data);

void HeapDelete(Heap* pH);

int HeapSize(Heap* pH);

int HeapTop(Heap* pH);

int HeapEmpty(Heap* pH);

void HeapTest();

void HeapSort(int* arr, int size, Compare compare);

void TestSort();

2. Heap.c

#include "Heap.h"

int Greater(int x, int y) { return x > y; }
int Less(int x, int y) { return x < y; }

void Swap(int* x, int* y) {
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

void AdjustDown(Heap* pH, int root) {
    assert(pH);

    int* arr = pH->arr;
    int parent = root;
    int child = parent * 2 + 1;  // left child

    while (child < pH->size) {
        if (child + 1 < pH->size && pH->compare(arr[child + 1], arr[child])) {
            child++;
        }

        if (pH->compare(arr[child], arr[parent])) {
            Swap(&arr[child], &arr[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else {
            break;
        }
    }
}

void HeapInit(Heap* pH, int* arr, int size, Compare com) {
    assert(pH);

    pH->arr = (int *)malloc(sizeof(int) * size);
    if (pH->arr == NULL) {
        perror("malloc error");
        exit(0);
    }

    memcpy(pH->arr, arr, size * 4);
    pH->capacity = size;
    pH->size = size;
    pH->compare = com;

    for (int root = (pH->size - 2) / 2; root >= 0; root--) {
        AdjustDown(pH, root);
    }
}

void HeapDestroy(Heap* pH) {
    assert(pH);

    free(pH->arr);
}

void CheckCapacity(Heap* pH) {
    assert(pH);

    if (pH->size == pH->capacity) {
        int* newArr = (int *)realloc(pH->arr, sizeof(int) * pH->capacity * 2);
        if (newArr == NULL) {
            perror("realloc error");
            exit(0);
        }

        pH->arr = newArr;
        pH->capacity *= 2;
    }
}

void AdjustUp(Heap* pH, int index) {
    assert(pH);

    int* arr = pH->arr;
    int child = index;
    int parent;

    while (child) {
        parent = (child - 1) / 2;

        if (pH->compare(arr[child], arr[parent])) {
            Swap(&arr[child], &arr[parent]);
            child = parent;
        }
        else {
            break;
        }
    }
}

void HeapInsert(Heap* pH, int data) {
    assert(pH);

    CheckCapacity(pH);

    pH->arr[pH->size] = data;
    pH->size++;
    AdjustUp(pH, pH->size - 1);
}

void HeapDelete(Heap* pH) {
    assert(pH);

    if (HeapEmpty(pH)) {
        return;
    }

    Swap(&(pH->arr[0]), &(pH->arr[pH->size - 1]));
    pH->size--;
    AdjustDown(pH, 0);
}

int HeapSize(Heap* pH) {
    return pH->size;
}

int HeapTop(Heap* pH) {
    return pH->arr[0];
}

int HeapEmpty(Heap* pH) {
    return pH->size == 0;
}

void HeapTest() {
    int arr[] = { 3, 7, 4, 2, 5, 1, 9, 8, 6, 0 };
    Heap h;

    HeapInit(&h, arr, sizeof(arr) / sizeof(arr[0]), Less);  // 小堆
    HeapDelete(&h);
    HeapDelete(&h);
    HeapInsert(&h, -1);
    HeapInsert(&h, -2);
    HeapInsert(&h, 10);

    printf("\n");
}
最后修改:2019 年 09 月 08 日
如果觉得我的文章对你有用,请随意赞赏