【数据结构---24】顺序结构存储二叉树堆

    xiaoxiao2022-07-13  163

    heap.h

    #pragma once typedef int HPDataType; typedef struct Heap { HPDataType* _array; int _capacity; int _size; }Heap; // 用数组初始化堆 void InitHeap(Heap* hp, HPDataType* array, int size); // 初始化一个空堆 void InitEmptyHeap(Heap* hp, int capacity); // 在堆中插入值为data的元素 void InsertHeap(Heap* hp, HPDataType data); // 删除堆顶元素 void EraseHeap(Heap* hp); // 获取堆中有效元素个数 int HeapSize(Heap* hp); // 检测堆是否为空堆 int HeapEmpty(Heap* hp); // 获取堆顶元素 HPDataType HeapTop(Heap* hp); // 销毁堆 void DestroyHeap(Heap* hp); //检测容量 void CheckCapacity(Heap* hp);

    heap.c

    #include "heap.h" #include<stdio.h> #include <assert.h> #include <malloc.h> void swap(HPDataType*a, HPDataType*b) { HPDataType tmp = 0; tmp = *a; *a = *b; *b = tmp; } void AdjustDown(HPDataType* array, int size, int parent) { int child = parent * 2 + 1; //找双亲中较小的孩子 while (child < size) { //必须保证右孩子存在 if (child + 1 < size && array[child + 1] < array[child]) { child += 1; } if (array[child] < array[parent]) { swap(&array[child], &array[parent]); parent = child; child = parent * 2 + 1; } else { return; } } } void AdjustUp(HPDataType* array, int size, int child) { int parent = (child - 1) / 2; while (child != 0) { if (array[child] < array[parent]) { swap(&array[child], &array[parent]); child = parent; parent = (child - 1) / 2; } } } void InitHeap(Heap* hp, HPDataType* array, int size) { assert(hp); //把给的数组中的元素都拷贝到堆里,size是数组长度 hp->_array = (HPDataType*)malloc(sizeof(HPDataType)*size); hp->_capacity = size; hp->_size = 0; for (int i = 0; i < size; ++i) { hp->_array[i] = array[i]; } hp->_size = size; int lastleaf = ((size - 2) >> 1); //等于0也是要调整的 while (lastleaf >= 0) { AdjustDown(hp->_array, size, lastleaf); lastleaf--; } } void InitEmptyHeap(Heap* hp, int capacity); void InsertHeap(Heap* hp, HPDataType data) { assert(hp); CheckCapacity(hp); hp->_array[hp->_size] = data; hp->_size++; AdjustUp(hp->_array, hp->_size, hp->_size - 1); } void EraseHeap(Heap* hp) { assert(hp); if (hp->_size == 0) { return; } //把堆顶元素和最后一个元素互换,然后size--;在向下调整 swap(&hp->_array[0], &hp->_array[hp->_size - 1]); hp->_size--; AdjustDown(hp->_array, hp->_size, 0); } int HeapSize(Heap* hp) { assert(hp); return hp->_size; } void CheckCapacity(Heap* hp) { assert(hp); if (hp->_size == hp->_capacity) { int newcapacity = hp->_capacity * 2; HPDataType* tmp = (HPDataType*)malloc(sizeof(HPDataType)*newcapacity); if (tmp == NULL) { return; } for (int i = 0; i < hp->_size; ++i) { tmp[i] = hp->_array[i]; } //释放旧空间 free(hp->_array); hp->_array = tmp; hp->_capacity = newcapacity; } } int HeapEmpty(Heap* hp) { assert(hp); if (hp->_size == 0) { return -1; } return 1; } HPDataType HeapTop(Heap* hp) { assert(hp); if (hp->_size == 0) { return -1; } return hp->_array[0]; } void DestroyHeap(Heap* hp) { assert(hp); if (hp->_array != NULL) { free(hp->_array); hp->_array = NULL; hp->_size = 0; hp->_capacity = 0; } } void HeapTest() { Heap hp; int a[] = { 27, 15, 19, 18, 28, 34, 65, 49, 25, 37 }; InitHeap(&hp, a, sizeof(a) / sizeof(a[0])); printf("size=%d\n", HeapSize(&hp)); printf("堆顶:%d\n", HeapTop(&hp)); EraseHeap(&hp); printf("删除堆顶元素成功!\n"); printf("size=%d\n", HeapSize(&hp)); printf("堆顶:%d\n", HeapTop(&hp)); InsertHeap(&hp, 13); printf("插入元素成功!\n"); printf("size=%d\n", HeapSize(&hp)); printf("堆顶:%d\n", HeapTop(&hp)); InsertHeap(&hp, 0); printf("插入元素成功!\n"); printf("size=%d\n", HeapSize(&hp)); printf("堆顶:%d\n", HeapTop(&hp)); EraseHeap(&hp); printf("删除堆顶元素成功!\n"); printf("size=%d\n", HeapSize(&hp)); printf("堆顶:%d\n", HeapTop(&hp)); //DestroyHeap(&hp); } int main() { HeapTest(); system("pause"); return 0; }

    代码运行测试图: 

     

     

    对代码进行优化:完成可以指定创建大堆还是小堆

     

     

    创建一个函数指针:

    typedef int(*PCom)(HPDataType, HPDataType); typedef struct Heap { HPDataType* _array; int _capacity; int _size; PCom compare; }Heap;

    给初始化和向上向下调整加入参数:

    void InitHeap(Heap* hp, HPDataType* array, int size,PCom compare); void AdjustDown(HPDataType* a, int size, int parent, PCom compare) void AdjustUp(HPDataType* a, int size, int child,PCom compare)

    具体比较的实现:

    int less(HPDataType a, HPDataType b) { return a<b; } int Greater(HPDataType a, HPDataType b) { return a>b; }

    对原先比较的修改:

    向下调整中: if (child + 1 < size && compare(a[child + 1] , a[child])) { child += 1; } if (compare(a[child] , a[parent])) { swap(&a[child], &a[parent]); parent = child; child = parent * 2 + 1; } 向上调整中: if (compare(a[child] , a[parent])) { swap(&a[child], &a[parent]); child = parent; parent = (child - 1) / 2; }

    调用时的参数传递:

    AdjustDown(hp->_array, size, lastleaf,hp->compare); AdjustUp(hp->_array, hp->_size, hp->_size - 1,hp->compare);

    代码运行测试图:

     

    堆的排序:

     

    void HeapAdjust(int* array, int size, int parent) { int child = parent * 2 + 1; while (child < size) { // 找左右孩子中较大的孩子 if (child + 1 < size && array[child + 1] > array[child]) child += 1; if (array[child] > array[parent]) { Swap(&array[child], &array[parent]); parent = child; child = parent * 2 + 1; } else { return; } } } void HeapSort(int* array, int size) { //建堆 int root = ((size - 1) >> 1); for (root; root >= 0; --root) { HeapAdjust(array, size, root); } //排序 int end = size - 1; while (end != 0) { swap(&array[0], &array[end]); HeapAdjust(array, end, 0); end--; } }

    TOP K问题在【数据结构---26】中 

     

    最新回复(0)