堆的建立及增删查改等操作
Posted 银背欧尼酱
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆的建立及增删查改等操作相关的知识,希望对你有一定的参考价值。
heap.c
#include <malloc.h>
#include <stdio.h>
void Swap(DataType* left, DataType* right)
{
int temp = *left;
*left = *right;
*right = temp;
}
void AdjustDown(DataType array[], int size, int parent)
{
//默认让parent标记左孩子,因为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(DataType array[], int size)
{
int child = size - 1;
int parent = (child - 1)/2;
while (child)
{
if (array[child] < array[parent])
{
Swap(&array[child], &array[parent]);
child = parent;
parent = (child - 1) / 2;
}
else
{
return;
}
}
}
//***********************************************
//建堆操作,巨重要!!
//整个程序的难点就在这里,这里理解了后面的就都可以理解
void HeapInit(Heap* hp, DataType* array, DataType size)
{
int LastNotLeaf = 0;
assert(hp);
hp->array = (DataType*)malloc(sizeof(DataType) * 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;
//1.找到最后一个非叶子节点
LastNotLeaf = (size - 2)/2;
//2.从该节点位置逐个往前直到根节点,遇到一个结点应用‘向下调整’
for (int root = LastNotLeaf; root >= 0; root--)
{
AdjustDown(hp->array,hp->size,root);
}
}
//***************************************************
void CheckCapacity(Heap* hp)
{
assert(hp);
if (hp->size == hp->capacity)
{
hp->array = (DataType*)realloc(hp->array, sizeof(DataType)*hp->size*2);
if (NULL == hp->array)
{
assert(0);
return;
}
hp->capacity *= 2;
}
}
//插入
void HeapInsert(Heap* hp, DataType data)
{
//1.先检测空间是否足够,如果不够进行扩容
CheckCapacity(hp);
//2.将元素插入到最后一个有效元素之后
hp->array[hp->size++] = data;
//3.插入的新元素可能破坏堆的特性,因此需要对堆进行调整
//这里选择‘向上调整’
AdjustUp(hp->array, hp->size);
}
//删除堆顶元素
//**************************************
//删除原理
//1.将堆顶元素与堆中最后一个元素交换
//2.将有效元素个数减去1
//3.将堆顶元素'往下调整'
void HeapErase(Heap* hp)
{
if (HeapEmpty(hp))
return;
//1.将堆顶元素与堆中最后一个元素交换
Swap(&hp->array[0], &hp->array[hp->size - 1]);
//2.将有效元素个数减去1
hp->size -= 1;
//3.将堆顶元素往下调整
AdjustDown(hp->array, hp->array, 0);
}
//获取堆顶元素
DataType HeapTop(Heap* hp)
{
//assert(hp);因为HeapEmpty函数中进行了assert(hp)判断
//所以此处不用再次判断
assert(!HeapEmpty(hp));
return hp->array[0];
}
DataType HeapEmpty(Heap* hp)
{
assert(hp);
return 0 == hp->size;
}
int HeapSize(Heap* hp)
{
assert(hp);
return hp->size;
}
void HeapDestory(Heap* hp)
{
assert(hp);
if (hp->array)
{
free(hp->array);
hp->array = NULL;
hp->capacity = 0;
hp->size = 0;
}
}
void TestHeap()
{
int array[] = { 6,7,8,3,5,1 };
Heap hp;
HeapInit(&hp, array, sizeof(array) / sizeof(array[0]));
printf("top=%d\\n", HeapTop(&hp));
printf("size=%d\\n", HeapSize(&hp));
HeapErase(&hp);
printf("top=%d\\n", HeapTop(&hp));
printf("size=%d\\n", HeapSize(&hp));
HeapInsert(&hp, 9);
printf("top=%d\\n", HeapTop(&hp));
printf("size=%d\\n", HeapSize(&hp));
HeapDestory(&hp);
}
heap.h
typedef int DataType;
typedef struct Heap
{
DataType* array;
DataType capacity;
DataType size;
}Heap;
void HeapInit(Heap* hp, DataType* array,DataType size);
//插入
void HeapInsert(Heap* hp, DataType data);
//删除
void HeapErase(Heap* hp);
//获取堆顶元素
DataType HeapTop(Heap* hp);
DataType HeapEmpty(Heap* hp);
int HeapSize(Heap* hp);
void HeapDestory(Heap* hp);
//
//测试
void TestHeap();
以上是关于堆的建立及增删查改等操作的主要内容,如果未能解决你的问题,请参考以下文章