堆的实现 包括向下调整,向上调整算法,堆的插入与删除以及获取堆顶元素,堆排序

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
typedef int HPDataType;

typedef struct Heap {
    HPDataType* _array;
    size_t _size;
    size_t _capacity;
}Heap;


void swap(HPDataType* array, int child, int parent) {
    int tmp = array[child];
    array[child] = array[parent];
    array[parent] = tmp;
}

向下调整(以建大堆为例):   前提: --> 子树已经是一个堆

①.起始位置(父节点)

②.计算孩子位置

③.从两个孩子中选择一个最大值

④.如果孩子大于父节点,交换,更新父节点和孩子节点,继续第③步

⑤.如果没有孩子,或者父节点是 孩子中最大的,结束调整

//向下调整,建小堆
void shiftdown1(HPDataType* array, int size, int parent) {
    int child = 2 * parent + 1;
    while (child < size) {
        if (child + 1 < size&& array[child] > array[child + 1])
            child++;
        if (array[child] < array[parent]) {
            swap(array, child, parent);
            parent = child;
            child = 2 * parent + 1;
        }
        else
            break;
    }
}
//向下调整,建大堆
void shiftdown(HPDataType* array, int size, int parent) {
    int child = 2 * parent + 1;
    while (child < size) {
        if (child + 1 < size&& array[child] < array[child + 1])
            child++;
        if (array[child] > array[parent]) {
            swap(array, child, parent);
            parent = child;
            child = 2 * parent + 1;
        }
        else
            break;
    }
}


void HeapCreat(Heap* hp, HPDataType* array, int size) {
    hp->_array = (HPDataType*)malloc(sizeof(HPDataType)*size);
    memcpy(hp->_array, array, sizeof(HPDataType)*size);
    hp->_capacity = size;
    hp->_size = size;

    for (int parent = (size - 2) / 2; parent >= 0; parent--) {
        shiftdown(hp->_array, size, parent);
    }
}

向上调整(以建大堆为例):   前提-->除过最后节点,其它节点构成的子结构已经是一个堆

①.起始位置

②.计算父亲的位置

③.比较起始位置和父亲位置的大小,如果起始位置大于父节点,交换,更新起始位置,继续执行第②步

④.没有父亲,或者起始位置小于父节点,结束调整
//向上调整,建小堆
void shiftup1(HPDataType* array, int child) {
    int parent = (child - 1) / 2;
    while (child > 0) {
        //前提是小根堆已经建好
        if (array[child] < array[parent]) {
            swap(array, child, parent);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}
//向上调整,建大堆
void shiftup(HPDataType* array, int child) {
    int parent = (child - 1) / 2;
    while (child > 0) {
        //前提是大根堆已经建好
        if (array[child] > array[parent]) {
            swap(array, child, parent);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}
//尾插


void HeapPush(Heap* hp,HPDataType data) {
    //检查容量
    if (hp->_size == hp->_capacity) {
        hp->_capacity *= 2;
        hp->_array = (HPDataType*)realloc(hp->_array, sizeof(HPDataType)*hp->_capacity);
    }
    //尾插
    hp->_array[hp->_size++] = data;

    //向上调整
    shiftup(hp->_array, hp->_size - 1);
}
//删除堆顶元素
void HeapPop(Heap* hp) {
    if (hp->_size > 0) {
        //交换:堆顶和最后一个叶子
        swap(hp->_array, 0, hp->_size - 1);
        //尾删:实际删除的是堆顶元素

        //删除效率高:O(1)
        hp->_size--;
        //向下调整
        shiftdown(hp->_array, hp->_size, 0);
    }
}
//获取堆顶元素
HPDataType HeapTop(Heap* hp) {
    return hp->_array[0];
}
//判空
int HeapEmpty(Heap* hp) {
    if (hp->_size == 0)
        return 1;
    return 0;
}
//堆打印
void HeapPrint(Heap* hp) {
    for (size_t i = 0; i < hp->_size; i++) {
        printf("%d ", hp->_array[i]);
    }
    printf("\n");
}

void test() {
    Heap hp;
    int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
    HeapCreat(&hp, array, 11);
    HeapPrint(&hp);
}

void test1() {
    Heap hp;
    int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
    int n = sizeof(array) / sizeof(array[0]);
    HeapCreat(&hp, array, n);
    HeapPrint(&hp);
    HeapPush(&hp, 7);
    HeapPrint(&hp);
    HeapPop(&hp);
    HeapPrint(&hp);
}
void test2() {
    Heap hp;
    int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
    int n = sizeof(array) / sizeof(array[0]);
    HeapCreat(&hp, array, n);
    HeapPrint(&hp);
    while (HeapEmpty(&hp) != 1) {
        printf("%d\n",HeapTop(&hp));
        HeapPop(&hp);
    }
}

//堆排序
void HeapSort(int* array, int n) {
    for (int i = (n - 2) / 2; i >= 0; i--) {
        shiftdown(array,n,i);
    }
    while (n > 1) {
        swap(array, 0, n - 1);
        n--;
        shiftdown(array, n, 0);
    }
}
void test3() {
    int array[11] = { 100,50,30,20,25,18,10,5,15,21,23 };
    int n = sizeof(array) / sizeof(array[0]);
    HeapSort(array, n);
    for (int i = 0; i < n; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
}

int main() {
    //test();
    //test1();
    //test2();
    test3();
    system("pause");
    return 0;
}
 

发布了42 篇原创文章 · 获赞 0 · 访问量 1430

猜你喜欢

转载自blog.csdn.net/HUAERBUSHI521/article/details/105597811
今日推荐