如何创建一个堆(大堆),以及实现插入删除

 在开始之前有兴趣的hxd可以去看看下面这篇博客,这样可以更好理解以下内容

​​​​​​​堆的特殊实现(向下调整算法)及排序_darling-02的博客-CSDN博客

目录

 堆的定义

堆的创建(初始化)

 堆的销毁

堆的插入

堆的删除

获取堆顶元素

堆的数据个数

 堆是否为空

堆的打印


​​​​​​​

 堆的定义

用一个结构体定义:一个数组(可动态增长),数组的大小,数组的数据

//大堆
typedef int TypeHeapDate;
typedef struct Heap
{
	TypeHeapDate* a;(动态可增长的数组)
	int size;//堆的数据个数
	int capacity;//容量(数组的大小)
}Heap;

堆的创建(初始化)

注意开辟空间后里面的数组,不一定是堆,所以需要建堆churu

void HeapCreate(Heap* php, TypeHeapDate* a, int sn)
{
	assert(php);

	php->a = (TypeHeapDate*)malloc(sizeof(TypeHeapDate)*sn);
	if (php->a == NULL)
	{
		printf("file of malloc");
		exit(-1);
	}
	//拷贝过去 方便后面删除插入(需要开辟空间)
	memcpy(php->a,a,sizeof(TypeHeapDate)*sn);
	php->capacity = php->size = sn;
	//建堆 -》大堆
	for (int i = (sn - 1 - 1) / 2; i >= 0; i--)
	{
		AdjustDownward(php->a,php->size,i);
	}
}

 堆的销毁

void HeapDestroy(Heap* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->capacity = php->size = 0;
}

堆的插入

插入的数插入后(此时它是数组最后一个数),需要和它的父节点比较

大堆:比父节点小不用向上调整,比父节点大向上调整

例如·在下面数组中插入8 和 88 

 

void AdjustUp(int*a,int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if(a[child] > a[parent])
		{
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

void HeapPush(Heap* php, TypeHeapDate x)
{
	assert(php);

	//满了需要增容
	if (php->capacity == php->size)
	{
		TypeHeapDate* newspace = (TypeHeapDate*)realloc(php->a,sizeof(TypeHeapDate)*php->capacity*2);
		if (newspace == NULL)
		{
			printf("file of relloc");
			exit(-1);
		}
		php->a = newspace;
		php->capacity *= 2;
	}
	//int push = php->size - 1;
	php->a[php->size] = x;
	php->size++;
	//插入后需要考虑插入数的大小 需要向上调正
	AdjustUp(php->a,php->size-1);
}

堆的删除

堆是删除堆顶的数据,将堆顶的数据根最后一个数据一换,然后删除数组最后一个数据,再进行向下调整

void HeapPop(Heap* php)
{
	assert(php);
	//保证有数可删
	assert(php->size > 0);
	//删除先把第一个和最后一个数交换 重新向下调整
	Swap(&php->a[0], &php->a[php->size - 1]);
	php->size--;

		AdjustDownward(php->a, php->size, 0);

}

获取堆顶元素

TypeHeapDate HeapTop(Heap* php)
{
	assert(php);
	assert(php->size > 0);

	return php->a[0];
}

堆的数据个数

int HeapSize(Heap* php)
{
	assert(php);
	assert(php->size > 0);

	return php->size;
}

 堆是否为空

bool HeapEmpty(Heap* php)
{
	assert(php);
	return php->size == 0;

}

堆的打印

void HeapPrint(Heap* php) 
{
	/*for (int j = 0;j < php->size;j++)
	{
		printf("%d ",php->a[j]);
	}
	printf("\n");*/
	int num = 0;
	int maxnum = 1;
	for (int i = 0; i < php->size; i++)
	{
		printf("%d ",php->a[i]);
		num++;
        //控制打印出来每行的个数
		if (num == maxnum)
		{
			printf("\n");
			maxnum *= 2;
			 num = 0;
		}
	}
	printf("\n\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值