您的位置:首页 > 理论基础 > 数据结构算法

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

2019-05-25 23:10 302 查看

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;
24000

}
}
}

//堆向上调整算法
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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: