c语言实现顺序结构的存储二叉树堆

堆是一个完全二叉树,堆分两种,一种为小堆,一种为大堆
小堆是指对于这个树的任意任意一个子树来说,子树的根节点都要小于左右孩子节点的值,小堆的根节点是这个树的最小元素,每条路径上的节点都是递增的
大堆是指对于这个树的任意任意一个子树来说,子树的根节点都要大于左右孩子节点的值,大堆的根节点是这个树的最大元素,每条路径上的节点都是递减的
堆的结构定义如下:
其中compare函数用来缺点创建的是大堆还是小堆,Greater选择创建大堆,Less选择创建小堆

#pragma once

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;
	HPDataType _capacity;
	HPDataType _size;
	PCOM compare;
}Heap;

void InitHeap(Heap* hp, HPDataType* array, int size, PCOM compare);
void InitEmptyHeap(Heap* hp, int capacity, PCOM compare);
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 AdjustDown(Heap* hp, size_t index)
{
	assert(hp);
	size_t parent = index;
	size_t child = 2 * index + 1;
	while (child  < hp->_size)
	{
		if ((child + 1 < hp->_size) && hp->compare(hp->_array[child] ,hp->_array[child + 1]))
		{
			child = child + 1;  //判断左子树合适还是右子树合适;
		}
		if (hp->compare(hp->_array[parent] , hp->_array[child]))
		{
			swap(&hp->_array[parent], &hp->_array[child]);
		}

		parent = child;
		child = 2 * parent + 1;
	}

}
void InitHeap(Heap* hp, HPDataType* array, int size,PCOM compare)
{
	assert(hp);
	HPDataType* _arr = (HPDataType*)malloc(sizeof(HPDataType)*size);
	if (_arr == NULL)
	{
		assert(0);
		return NULL;
	}
	hp->_array = _arr;
	for (int i = 0; i<size; ++i)
	{
		hp->_array[i] = array[i];
	}

	hp->_capacity = size;
	hp->_size = size;
	hp->compare = compare;
}

//创建一个堆结构
void CreatHeap(Heap* hp)
{
	assert(hp);
	for (int dep = (hp->_size - 1) / 2; dep >= 0; --dep)
	{
		AdjustDown(hp, dep);
	}
}

查看堆顶元素,查看堆成员个数等操作

//取堆顶元素
HPDataType HeapTop(Heap* hp)
{
	assert(hp);
	if (hp->_size == 0)
	{
		return;
	}
	return hp->_array[0];
}

//删除堆顶操作操作
void EraseHeap(Heap *hp)
{
	assert(hp);
	if (hp->_size == 0)
	{
		return NULL;
	}
	swap(&hp->_array[0], &hp->_array[hp->_size - 1]);
	hp->_size--;
	AdjustDown(hp, 0);
}

int HeapSize(Heap* hp)
{
	assert(hp);
	return hp->_size;
}

int HeapEmpty(Heap* hp)
{
	assert(hp);
	if (!hp->_size)
	{
		return 1;
	}
	return 0;
}

HPDataType Head_Is_Full(Heap* hp)
{
	assert(hp);
	if (hp->_capacity == hp->_size)
	{
		return 1;
	}
	return 0;
}

//在堆中插入值为Data的元素
void InsertHeap(Heap* hp, HPDataType data)
{
	assert(hp);
	//容量不够,进行扩容
	if (Head_Is_Full)
	{
		int newcapacity = hp->_capacity * 2;
		HPDataType * newarr = (HPDataType *)malloc(sizeof(HPDataType) * newcapacity);
		if (newarr == NULL)
		{
			assert(0);
			return NULL;
		}
		for (int i = 0; i < hp->_size; ++i)
		{
			newarr[i] = hp->_array[i];
		}
		hp->_array = newarr;
		hp->_capacity = newcapacity;
	}
	hp->_array[hp->_size] = data;
	CreatHeap(hp);
	hp->_size++;
}

void DestroyHeap(Heap* hp)
{
	assert(hp);
	free(hp->_array);
	hp->_capacity = 0;
	hp->_size = 0;
}

实现堆排序,解决TOP k问题
Greater为升序排列
Less为降序排列

void SortHeap(HPDataType *_arr, size_t size)
{
	Heap hp;
	InitHeap(&hp, _arr, size,Greater);
	CreatHeap(&hp);
	for (int i = 0; i < size; ++i)
	{
		EraseHeap(&hp);
	}
	hp._size = size;
	//升序取前5个数
	for (int i = size-1; i >= 0; --i)
	{
		printf("%d ", hp._array[i]);
	}
	DestroyHeap(&hp);
}
int main()
{
	int _arr[] = { 8,7,6,5,1,3,6,8,9,0,2,11,15,17,19 };
	int size = sizeof(_arr) / sizeof(_arr[0]);
	SortHeap(_arr, size);
	system("pause");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值