经典数据结构——堆的实现(最全功能、包含TopK)

这篇博客详细介绍了如何创建一个最小堆的数据结构,包括初始化、插入、删除、获取堆顶元素、判断堆是否为空、销毁堆以及打印堆内容等操作。此外,还提供了一个用于找出数组中最大K个数的函数。通过示例代码展示了堆的使用,并进行了测试,以验证其正确性和效率。
摘要由CSDN通过智能技术生成

//创建一个堆的结构体

typedef int HPDataType;
typedef struct Heap{

	HPDataType* _a;
	int _size;
	int _capacity;


}Heap;

// 堆的构建
void HeapInit(Heap* hp, HPDataType* a, int n);

//堆的插入
void HeapPush(Heap* hp, HPDataType x);
//堆的删除
void HeapPop(Heap* hp);
//取堆顶的数据
int HeapTop(Heap* hp);
//堆的数据个数
int HeapSize(Heap* hp);
//堆的判空
int HeapEmpty(Heap* hp);
// 堆的销毁
void HeapDestory(Heap* hp);
//打印堆的数据
void HeapPrint(Heap *hp);


void AdjustDown(HPDataType* a, int n, int root);
void AdjustUp(HPDataType *a, int n, int child);
void swap(HPDataType *a, HPDataType* b);


void HeapInit(Heap *hp, HPDataType* a, int n)
{

	int i;
	assert(hp&&a);
	hp->_a = (HPDataType*)malloc(sizeof(HPDataType)*n);
	hp->_size = n;
	hp->_capacity = n;

	for (i = 0; i < n; ++i)
	{
		hp->_a[i] = a[i];

	}
	for (int i = (n - 2) / 2; i >= 0; --i)
	{
		AdjustDown(hp->_a, hp->_size, i);

	}

}


void HeapPush(Heap *hp, HPDataType x)
{

	assert(hp);
	if (hp->_size == hp->_capacity)
	{

		hp->_a= (HPDataType*)realloc(hp->_a,  2 * sizeof(HPDataType)*hp->_capacity);
		hp->_capacity *= 2;

		hp->_a[hp->_size] = x;
		hp->_size++;

		AdjustUp(hp->_a, hp->_size, hp->_size - 1);


	}

}
//先将首尾元素交换,堆的删除是删除堆顶的元素,再进行向下调整法
void HeapPop(Heap *hp)
{
	assert(hp);
	swap(&hp->_a[0], &hp->_a[hp->_size - 1]);
	hp->_size--;
	AdjustDown(hp->_a, hp->_size, 0);


}

int HeapTop(Heap *hp)
{

	assert(hp);
	return hp->_a[0];


}

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

}

int HeapEmpty(Heap* hp)
{
	return hp->_size == 0;
}



void swap(int *a, int* b)
{

	int tmp = *a;
	*a = *b;
	*b = tmp;


}

//找最大的K个数
void PrintTopK(int *a, int n, int k)
{
	int *heapA = (int*)malloc(sizeof(int)*k);
	for (int i = 0; i < k; ++i)
	{
		heapA[i] = a[i];
	}

	for (int i =(k-2)/2 ; i >=0; --i)
	{

		AdjustDown(heapA, k, i);

	}

	for (int j = k; j < n; ++j)
	{
		if (heapA[0] < a[j])
		{
			heapA[0] = a[j];
			AdjustDown(heapA, k, 0);
		}
		
	}

	for (int i = 0; i < k; ++i)
	{
		printf("%d\n", heapA[i]);
	}
	
}

//向上调整法
void AdjustUp(HPDataType *a, int n, int child)
{
	assert(a);
	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 AdjustDown(HPDataType* a, int n, int root)
{

	int parent = root;
	int child = parent * 2 + 1;

	while (child<n)
	{
		if (child+1<n&&a[child] > a[child + 1])
		{
			child++;
		}
		if (a[child] < a[parent])
		{
			swap(&a[child], &a[parent]);
			parent = child;
			child = parent * 2 + 1;

		}

		else{
			break;

		}

	}

	
}

void HeapPrint(Heap *hp)
{
	for (int i = 0; i < hp->_size; ++i)
	{
		printf("%d ", hp->_a[i]);

	}
	printf("\n");
}


void HeapDestroy(Heap *hp)
{
	assert(hp);
	free(hp->_a);
	hp->_a = NULL;
	hp->_capacity = hp->_size = 0;

}



void Test()
{
	int n = 10000;
	int *a = (int*)malloc(sizeof(int)*n);
	srand((size_t)time(NULL));
	for (int i = 0; i <n; ++i)
	{
		a[i] = rand() % 100000;

	}

	a[111] = 9999 + 100000;
	a[222] = 888 + 100000;
	a[333] = 777 + 100000;
	a[33] = 777 + 1000007;
	a[1200] = 1200 + 100000;
	a[2400] = 2400 + 100000;
	a[4500] = 4500 + 100000;
	a[3000] = 3000 + 100000;
	a[30] = 3020 + 100000;
	a[40] = 3444 + 100000;

	PrintTopK(a, n, 10);


}

void Test1()
{
	Heap hp;
	int n = 8;
	int *a = (int*)malloc(sizeof(int)*n);
	srand((size_t)time(NULL));
	for (int i = 0; i < n; ++i)
	{
		a[i] = rand() % 100;
	}
	HeapInit(&hp, a, n);

	HeapPush(&hp, 1);
	HeapPrint(&hp);
	printf("%d\n", HeapSize(&hp));

	HeapPop(&hp);
	HeapPrint(&hp);
	printf("%d\n", HeapSize(&hp));
	HeapSize(&hp);


}


int main()
{

	//Test();
	Test1();
	
	return 0;
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值