实现堆的各种基本运算的算法(数据结构)

以小堆为例,大堆就举一反三了。

堆的物理结构就是普通的数组,但是逻辑结构看成了一颗完全二叉树。

小堆,就是树的每一个父节点都小于他的孩子节点。如图中第一排的a与b。大堆,就是树的每一个父节点都大于他的孩子节点。如图中第二排的a与b。我们要实现的功能就是将一个数组排成符合要求的序列。

创建小堆

cpp 复制代码
typedef int HeapDataType;

typedef struct Heap//小堆
{
	HeapDataType* a;
	int size;
	int capacity;
}HP;

堆初始化

cpp 复制代码
//初始化堆
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->size = php->capacity = 0;
}

向堆增加数据

cpp 复制代码
//Push数据
void HeapPush(HP* php, HeapDataType x)
{
	assert(php);
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : php->capacity * 2;
		HeapDataType* temp = (HeapDataType*)realloc(php->a, sizeof(HeapDataType) * newcapacity);
		if (temp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		php->capacity = newcapacity;
		php->a = temp;
	}
	php->a[php->size++] = x;
	HeapAdjustUp(php->a, php->size-1);
}

删除堆顶数据

每一次删除堆顶元素,都会再次形成一个新的堆,新堆的堆顶元素就是数组a中次

小的值,再次删除,再形成新堆,堆顶就变成次次小的元素了。以此类推。

cpp 复制代码
//Pop数据
void HeapPop(HP* php)
{
	assert(php);
	assert(php->size > 0);
	Swap(&php->a[0], &php->a[php->size - 1]);
	php->size--;
	HeapAdjustDown(php->a, php->size, 0);
}

获得堆顶数据

cpp 复制代码
//获得堆顶数据
HeapDataType HeapTop(HP* php)
{
	assert(php);
	return php->a[0];
}

获得堆的有效大小

cpp 复制代码
//获得堆的有效大小
size_t HeapSize(HP* php)
{
	return php->size;
}

判断堆是否为空

cpp 复制代码
//判断堆是否为空
bool HeapEmpty(HP* php)
{
	assert(php);
	return php->size == 0 ? 1 : 0;
}

交换数据

cpp 复制代码
//交换数据
void Swap(HeapDataType* p1,HeapDataType* p2)
{
	HeapDataType p3 = *p1;
	*p1 = *p2;
	*p2 = p3;
}

向上调整数组形成堆

cpp 复制代码
//向上调整数组形成堆
void HeapAdjustUp(HeapDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while (child > 0)
	{
		if (a[parent] > a[child])
		{
			Swap(&a[parent], &a[child]);
			child = parent;
			parent = (child - 1) / 2;
		}
		else
		{
			break;
		}
	}
}

向下调整数组形成堆

cpp 复制代码
//向下调整数组形成堆
void HeapAdjustDown(int* a, int size, int parent)
{
	int child = parent * 2 + 1;
	while (child < size)
	{
		if (child + 1< size && a[child + 1] < a[child])
		{
			child++;
		}
		if (a[parent] > a[child])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = parent * 2 + 1;
		}
		else
		{
			break;
		}
	}
}

销毁堆

cpp 复制代码
//销毁堆
void HeapDestory(HP* php)
{
	assert(php);
	free(php->a);
	php->a = NULL;
	php->size = php->capacity = 0;
}

所需头文件

cpp 复制代码
#pragma once
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdbool.h"
#include "assert.h"

main函数测试

cpp 复制代码
#include "Heap.h"

int main()
{
	int a[] = { 4,6,2,1,5,8,2,9};
	HP hp;//创建堆
	HeapInit(&hp);//初始化堆
    
   //将数组a内数据Push到堆中
	for (int i = 0; i < sizeof(a) / sizeof(int); ++i)
	{
		HeapPush(&hp, a[i]);
	}

	
	int k = 3;
	while (k--)
	{
		printf("%d\n", HeapTop(&hp));
		HeapPop(&hp);//每一次删除堆顶元素,都会再次形成一个新的堆,新堆的堆顶元素就是数组a中次
                    //小的值,再次删除,再形成新堆,堆顶就变成次次小的元素了。以此类推。
                    //所以打出来的会是升序的
	}

	while (!HeapEmpty(&hp))
	{
		printf("%d\n", HeapTop(&hp));
		HeapPop(&hp);
	}
	printf("\n");

	return 0;
}

结果

相关推荐
On The Road :几秒前
深入理解 JVM 垃圾回收:GC 是什么、如何判定垃圾、四大回收算法全解析
jvm·算法
微尘hjx1 小时前
【Deep-OC-SORT 03】多轨迹算法Deep-OC-SORT-卡尔曼滤波预测过程
算法·yolo·目标跟踪·ultralytics·车跟踪·轨迹算法·deep-oc-sort
老师我太想进步了20263 小时前
【数据结构-3】算法美学之降复杂度
数据结构·算法
机器人零零壹8 小时前
技术白皮书:iRobotCAM如何解决机器人激光切割应用中的核心难点,从CAD离线编程到双目视觉定位与轨迹自适应提升复杂空间曲线切割的精度、效率与柔性化水平
人工智能·算法
ZhengEnCi11 小时前
大模型的分类到底怎么分:从基础模型到推理模型、从通用到专用的完整图谱
算法
取名真是12 小时前
Python 算法知识点从基础到进阶
开发语言·python·算法
罗西的思考12 小时前
【轻量化复刻大模型 / KIMI K3】KDA 模块交互式演示
人工智能·算法·机器学习
nm_zfyjt14 小时前
信息流广告投放优化实践:线索成本评估模型与转化链路重构(家装建材案例)
算法·重构·内蒙古朋友圈广告服务商·内蒙古朋友圈获客
w_zero_one15 小时前
算法--构造
java·数据结构·算法
其实防守也摸鱼16 小时前
信创安全竞赛知识总结与题库
大数据·网络·人工智能·算法·安全·php