数据结构【实现可控制大小的堆】

    xiaoxiao2023-11-25  151

    C语言实现可以控制创建大堆还是小堆

    前面用C语言实现了堆的接口,但是我们会发现用户如果想创建一个大堆和一个小堆,就需要堆代码进行重新修改,这样太过于麻烦。今天我们就用C语言用一个代码来实现两种堆的接口

    typedef int HPDataType; typedef int(*PCOM)(HPDataType, HPDataType); // 堆中元素进行小于比较 int Less(HPDataType left, HPDataType right); // 堆中元素进行大于比较 int Greater(HPDataType left, HPDataType right); typedef struct Heap { HPDataType* _array; int _capacity; int _size; PCOM Compare; // 函数指针变量,保存用户传递的比较中堆中元素方法 }Heap; void Swap(HPDataType* x, HPDataType* y) { HPDataType temp = *x; *x = *y; *y = temp; } void CheckCapacity(Heap* hp) { assert(hp); if (hp->_size == hp->_capacity) { int newCapacity = hp->_capacity * 2; HPDataType* pTemp = (HPDataType*)malloc(sizeof(HPDataType)*newCapacity); if (NULL == pTemp) { assert(0); return; } for (int i = 0; i < hp->_size; i++) { pTemp[i] = hp->_array[i]; } free(hp->_array); hp->_capacity = newCapacity; hp->_array = pTemp; } } //堆向下调整算法 void AdjustDown(HPDataType* array, int size, int parent,PCOM Compare) { //默认用child标记parent的左孩子,完全二叉树只有一个孩子的话,一定是左孩子 int child = parent * 2 + 1; //找双亲孩子中较小的孩子 while (child < size){ if (child + 1 < size && Compare(array[child + 1] , array[child])) { child += 1; } if (Compare(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,PCOM Compare) { int parent = (child - 1) / 2; while (child) { if (Compare(array[child] , array[parent])) { Swap(&array[child], &array[parent]); child = parent; parent = (child - 1) / 2; } else { return; } } } //空堆的初始化 void InitEmptyHeap(Heap* hp, int capacity, PCOM Compare) { assert(hp); hp->_array = (HPDataType*)malloc(sizeof(HPDataType)*capacity); if (NULL == hp->_array) { assert(0); return; } hp->_capacity = capacity; hp->_size = 0; hp->Compare = Compare; } // 堆中元素进行小于比较 int Less(HPDataType left, HPDataType right) { return left < right; } // 堆中元素进行大于比较 int Greater(HPDataType left, HPDataType right) { return left > right; } //堆的初始化 void InitHeap(Heap* hp, HPDataType* array, int size, PCOM Compare) { assert(hp); hp->_array = (HPDataType*)malloc(sizeof(HPDataType)*size); if (NULL == hp->_array) { assert(0); return; } hp->_capacity = size; for (int i = 0; i < size; i++) { hp->_array[i] = array[i]; } hp->_size = size; hp->Compare = Compare; //找到最后一个非叶子节点 int root = (size - 2) / 2; for (; root >= 0; root--){ AdjustDown(hp->_array, size, root,hp->Compare); } } //在堆中插入元素 void InsertHeap(Heap* hp, HPDataType* data) { CheckCapacity(&hp); hp->_array[hp->_size] = data; hp->_size++; ADjustUP(hp->_array, hp->_size, hp->_size - 1,hp->Compare); } //删除一个堆元素 void EarseHeap(Heap* hp) { if (HeapEmpty(hp)) return; Swap(&hp->_array[0], &hp->_array[hp->_size - 1]); hp->_size -= 1; AdjustDown(hp->_array, hp->_size, 0,hp->Compare); } //获取堆中有效元素个数 int HeapSize(Heap* hp) { assert(hp); return hp->_size; } //判断堆是否为空 int HeapEmpty(Heap* hp) { assert(hp); return 0 == hp->_size; } //获取堆顶元素 HPDataType HeapTop(Heap* hp) { assert(hp); return hp->_array[0]; } //销毁堆 void DestroyHeap(Heap* hp) { assert(hp); if (hp->_array) { free(hp->_array); hp->_capacity = 0; hp->_size = 0; } }
    最新回复(0)