二叉树顺序结构堆实现

news2024/11/27 8:24:53

目录

Test.c测试代码

test1

test2

test3

🎇Test.c总代码 

Heap.h头文件&函数声明

头文件

函数声明

🎇Heap.h总代码

Heap.c函数实现 

☁HeapInit初始化

☁HeapDestroy销毁

☁HeapPush插入数据

【1】插入数据

【2】向上调整Adjustup❗

数据交换Swap

☁HeapPop删除数据

【1】交换数据

【2】删除数据

【3】向下调整Adjustdown❗

假设法找Child 

数据交换Swap

☁HeapTop堆顶元素

☁HeapSize堆元素个数

☁HeapEmpty判断为空否

🎇Heap.c总代码 


拖了很久的【堆】,本周主要学习就是【数据结构】。本章【堆】是以【小堆】为例子。

  •  堆表面是数组,内核是完全二叉树/满二叉树
  • ❗HeapPush
  • ❗HeapPop
  • 函数如果需要多次复用才会提取出来
  • free会对NULL进行检查 
  • 用循环写起来很方便的代码就不要使用递归
  • do while循环用于无论循环条件如何,循环都会执行一次
  • 步骤--注意事项--循环结束条件--时间复杂度(下篇重点讲)

Test.c测试代码

#include"Heap.h"
int main()
{
	HP php;
	//HP*ph=&php
	//test1(&php);
	test2(&php);
	test3(&php);
	return 0;
}

test1

//建堆
void test1(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}
}

test2

//找出堆的前K个数字
void test2(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	int k = 5;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}

	while (k--)
	{
		printf("%d ", HeapTop(ph));
		HeapPop(ph);
	}
	printf("\n");
}

 

test3

//排序--升序
void test3(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}
	while (HeapEmpty(ph))//为NULLflase
	{
		printf("%d ", HeapTop(ph));
		HeapPop(ph);
	}
}

🎇Test.c总代码 

#include"Heap.h"
//建堆
void test1(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}
}

//找出堆的前K个数字
void test2(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	int k = 5;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}

	while (k--)
	{
		printf("%d ", HeapTop(ph));
		HeapPop(ph);
	}
	printf("\n");
}

void test3(HP* ph)
{
	int a[] = { 4,5,3,7,8,2,1,9,10 };
	HeapInit(ph);
	int i = 0;
	for (i = 0; i < sizeof(a) / sizeof(a[0]); i++)
	{
		HeapPush(ph, a[i]);
	}
	while (HeapEmpty(ph))//为NULLflase
	{
		printf("%d ", HeapTop(ph));
		HeapPop(ph);
	}
}

int main()
{
	HP php;
	//HP*ph=&php
	//test1(&php);
	test2(&php);
	test3(&php);
	return 0;
}

Heap.h头文件&函数声明

头文件

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int HpDataType;

//定义堆结构体
typedef struct Heap
{
	HpDataType* a;
	int size;
	int capacity;
}HP;

函数声明

//常用接口
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php,HpDataType x);
void HeapPop(HP* php);
HpDataType HeapTop(HP* php);
int HeapSize(HP* php);
bool HeapEmpty(HP* php);

🎇Heap.h总代码

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>

typedef int HpDataType;

//定义堆结构体
typedef struct Heap
{
	HpDataType* a;
	int size;
	int capacity;
}HP;

//常用接口
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php,HpDataType x);
void HeapPop(HP* php);
HpDataType HeapTop(HP* php);
int HeapSize(HP* php);
bool HeapEmpty(HP* php);

Heap.c函数实现 

☁HeapInit初始化

#include"Heap.h"
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

☁HeapDestroy销毁

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);//不用担心为NULL,free会对NULL做检查
	php->size = php->capacity = 0;
}

☁HeapPush插入数据

 先插入一个10到数组的尾上,再进行向上调整算法,直到满足堆。

【1】插入数据

void HeapPush(HP* php, HpDataType x)
{
	assert(php);
	//扩容
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;
		HpDataType* tmp = (HpDataType*)realloc(php->a, newcapacity * sizeof(HpDataType));
		if (tmp == NULL)
		{
			printf("fail realloc");
			return;
		}
		php->capacity = newcapacity;
		php->a = tmp;
	}
	//插入数据
	php->a[php->size] = x;
	php->size++;
	//向上调整//数组,调整元素下标
	AdjustUp(php->a, php->size - 1);
}

【2】向上调整Adjustup❗

//向上调整算法
void AdjustUp(HpDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while ( child > 0 )//此刻parent已经数组越界
	{
		if (a[child] < a[parent])
		{
			//交换
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else//child>=parent
		{
			break;
		}
	}
}
数据交换Swap
//交换
void Swap(HpDataType* H1, HpDataType* H2)
{
	HpDataType tmp = *H1;
	*H1 = *H2;
	*H2 = tmp;
}

☁HeapPop删除数据

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

//删除
void HeapPop(HP* php)
{
	assert(php);
	assert(php->size);

	//1.交换
	Swap(&php->a[0], &php->a[php->size - 1]);

	//2.删除
	php->size--;

	//3.向下调整--数组,结束条件size有关,调整的位置parent
	Adjustdown(php->a, php->size, 0);
}

【1】交换数据

	//1.交换
	Swap(&php->a[0], &php->a[php->size - 1]);

【2】删除数据

	//2.删除
	php->size--;

【3】向下调整Adjustdown❗

//3.向下调整--数组,结束条件size有关,调整的位置parent
Adjustdown(php->a, php->size, 0);
//向下调整
void Adjustdown(HpDataType* a, int size, int parent)
{
	//假设法
	int child = parent * 2 + 1;
	while (child < size )//why child < size && child+1<size
	{
		if (child + 1 < size && a[child + 1] < a[child])
		{
			child++;
		}
		//比较
		if (a[child] < a[parent])
		{
			//交换
			Swap(&a[child], &a[parent]);
			parent = child;
			child = child * 2 + 1;
		}
		else//>=
		{
			break;
		}
	}
}
假设法找Child 
	int child = parent * 2 + 1;
    if (a[child + 1] < a[child])
	{
		child++;
	}
数据交换Swap
//交换
void Swap(HpDataType* H1, HpDataType* H2)
{
	HpDataType tmp = *H1;
	*H1 = *H2;
	*H2 = tmp;
}

☁HeapTop堆顶元素

HpDataType HeapTop(HP* php)
{
	assert(php);
	assert(php->size);

	return php->a[0];
}

☁HeapSize堆元素个数

int HeapSize(HP* php)
{
	assert(php);
	return php->size;
}

☁HeapEmpty判断为空否

bool HeapEmpty(HP* php)
{
	assert(php);

	return php->size != 0;//!=0是true不为NULL执行   ==0 flase 不执行
}

🎇Heap.c总代码 

#include"Heap.h"
void HeapInit(HP* php)
{
	assert(php);
	php->a = NULL;
	php->size = 0;
	php->capacity = 0;
}

void HeapDestroy(HP* php)
{
	assert(php);
	free(php->a);//不用担心为NULL,free会对NULL做检查
	php->size = php->capacity = 0;
}
//交换
void Swap(HpDataType* H1, HpDataType* H2)
{
	HpDataType tmp = *H1;
	*H1 = *H2;
	*H2 = tmp;
}

//向上调整算法
void AdjustUp(HpDataType* a, int child)
{
	int parent = (child - 1) / 2;
	while ( child > 0 )//此刻parent已经数组越界
	{
		if (a[child] < a[parent])
		{
			//交换
			Swap(&a[child], &a[parent]);
			child = parent;
			parent = (parent - 1) / 2;
		}
		else//child>=parent
		{
			break;
		}
	}
}

void HeapPush(HP* php, HpDataType x)
{
	assert(php);
	//扩容
	if (php->size == php->capacity)
	{
		int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;
		HpDataType* tmp = (HpDataType*)realloc(php->a, newcapacity * sizeof(HpDataType));
		if (tmp == NULL)
		{
			printf("fail realloc");
			return;
		}
		php->capacity = newcapacity;
		php->a = tmp;
	}
	//插入数据
	php->a[php->size] = x;
	php->size++;
	//向上调整//数组,调整元素下标
	AdjustUp(php->a, php->size - 1);
}

//向下调整
void Adjustdown(HpDataType* a, int size, int parent)
{
	//假设法
	int child = parent * 2 + 1;
	while (child < size )//why child < size && child+1<size
	{
		if (child + 1 < size && a[child + 1] < a[child])
		{
			child++;
		}
		//比较
		if (a[child] < a[parent])
		{
			//交换
			Swap(&a[child], &a[parent]);
			parent = child;
			child = child * 2 + 1;
		}
		else//>=
		{
			break;
		}
	}
}
//删除
void HeapPop(HP* php)
{
	assert(php);
	assert(php->size);

	//1.交换
	Swap(&php->a[0], &php->a[php->size - 1]);

	//2.删除
	php->size--;

	//3.向下调整--数组,结束条件size有关,调整的位置parent
	Adjustdown(php->a, php->size, 0);
}

HpDataType HeapTop(HP* php)
{
	assert(php);
	assert(php->size);

	return php->a[0];
}


int HeapSize(HP* php)
{
	assert(php);
	return php->size;
}

bool HeapEmpty(HP* php)
{
	assert(php);

	return php->size != 0;//!=0是true不为NULL执行   ==0 flase 不执行
}

当然,【大堆】只要改变大小符号即可,如果你不想要改变,可以使用【回调函数】!! 

🙂感谢大家的阅读,若有错误和不足,欢迎指正!希望本周可以结束【初阶数据结构】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java JVM类加载阶段 双亲委派模式

类加载阶段 加载 将类的字节码载入方法区中&#xff0c;内部采用 C 的 instanceKlass 描述 java 类&#xff0c;它的重要 field 有&#xff1a; _java_mirror 即 java 的类镜像&#xff0c;例如对 String 来说&#xff0c;就是 String.class&#xff0c;作用是把 klass 暴露…

中国2023年土地利用现状遥感监测数据

中国2023年土地利用现状遥感监测数据是以2023年美国Landsat 8遥感影像为主要数据源&#xff0c;在2020年通过2020年土地利用数据基础上&#xff0c;通过2020年和2023年两期遥感影像对比分析&#xff0c;人工目视解译生成。 改革开放以来&#xff0c;中国经济的快速发展对土地利…

Docker进阶篇-reids集群

一、集群存储算法 分布式存储的常见算法&#xff1a; 哈希取余分区 一致性哈希算法分区 哈希槽分区 1、哈希取余分区 描述&#xff1a;每次读写操作都是根据公式&#xff1a;Hash(key) % N&#xff08;其中&#xff0c;key是要存入Redis的键名&#xff0c;N是 Redis集群的…

编程实例分享,配件进销存进出库管理系统软件

编程实例分享&#xff0c;配件进销存进出库管理系统软件 一、前言 以下教程以 佳易王配件进出库管理系统软件V16.0为例说明 如上图&#xff0c;左侧为导航栏&#xff0c;分为 系统设置&#xff0c;用户信息设置&#xff0c;出入库开单&#xff0c;统计报表&#xff0c;财务管…

BPF 管理器 bpfman 简介

1. 背景 Fedora 40 提案建议将 bpfman 作为默认的程序管理器 &#xff0c;开源项目 bpfman 可以实现对 eBPF 运行状态的深入了解&#xff0c;从而实现更轻松地管理 eBPF 程序&#xff08;包括加载、卸载、运行状态查看等&#xff09;。该提案还需要 Fedora 工程和指导委员会 (…

1.31学习总结

1.31 1.线段树 2.Bad Hair Day S&#xff08;单调栈&#xff09; 3.01迷宫(BFS连通块问题剪枝)&#xff08;连通性问题的并查集解法&#xff09; 4.健康的荷斯坦奶牛 Healthy Holsteins&#xff08;DFS&#xff09; 线段树与树状数组 线段树和树状数组的功能相似&#xff0c;但…

社交买量:归因统计的核心要素与工具

在当今的社交App推广领域&#xff0c;广告买量已成为企业获取用户的重要手段。然而&#xff0c;如何准确衡量这些买量活动的成效&#xff0c;即用户从广告访问到安装后行为的完整转化路径&#xff0c;一直是运营人员关注的焦点。归因统计是一种评估营销效果的关键技术方案&…

制造业实施QMS质量管理系统的作用是什么?

QMS质量管理系统是一个关键的组织管理工具&#xff0c;用于确保产品和服务的质量符合预期标准&#xff1b;通过有效地实施万界星空科技QMS&#xff0c;组织可以确保产品和服务的质量符合预期标准&#xff0c;提升客户满意度&#xff0c;增强市场竞争力。 一、QMS系统的特点&…

找出最可疑的嫌疑人 - 华为机试真题题解

考试平台&#xff1a; 时习知 分值&#xff1a; 100分&#xff08;第一题&#xff09; 考试时间&#xff1a; 2024-01-31 &#xff08;两小时&#xff09; 题目描述 民警侦办某商场店面盗窃案时&#xff0c;通过人脸识别针对嫌疑人进行编号1-100000。 现在民警在监控记录中发…

Prometheus---图形化界面grafana(二进制)

前言 Prometheus是一个开源的监控以及报警系统。整合zabbix的功能&#xff0c;系统&#xff0c;网络&#xff0c;设备。 proetheus可以兼容网络&#xff0c;设备。容器的监控。告警系统。因为他和k8s是一个项目基金开发的产品&#xff0c;天生匹配k8s的原生系统。容器化和云原…

运动编辑学习笔记

目录 跳舞重建&#xff1a; 深度运动重定向 Motion Preprocessing Tool anim_utils MotionBuilder 跳舞重建&#xff1a; https://github.com/Shimingyi/MotioNet 深度运动重定向 https://github.com/DeepMotionEditing/deep-motion-editin 游锋生/deep-motion-editin…

Three.js学习1:threejs简介及文档本地部署

开一个天坑&#xff0c;Three.js 我觉得未来3D页面一定是一个趋势。 -----------------------------华丽的分割线------------------------- github&#xff1a;https://github.com/mrdoob/three.js/ 官网&#xff1a;Three.js – JavaScript 3D Library Threejs官网中文文…

自学Java的第十八天

一&#xff0c;每日收获 1.数组拷贝 2.数组反转 3.数组添加/扩容 二&#xff0c;新名词与小技巧 三&#xff0c;今天学习中所遇到的困难 一&#xff0c;每日收获 1.数组拷贝 编写代码 实现数组拷贝 将 int[] arr1 {10,20,30}; 拷贝到 arr2 数组 , 要求数据空间是独…

LVGL部件4

一.列表部件 1.知识概览 2.函数接口 1.lv_list_add_btn lv_list_add_btn 是 LittlevGL&#xff08;LVGL&#xff09;图形库中的一个函数&#xff0c;用于向列表&#xff08;list&#xff09;对象中添加一个按钮&#xff08;button&#xff09;。 函数原型为&#xff1a;lv_ob…

DRV8301 踩坑记,Status1 D10 老是 Fault

波形如上&#xff1a; 看第一个时钟出来的数据&#xff08;Status1 读完自动清除&#xff1f;&#xff09;&#xff0c;因此数据是&#xff1a;0x20 输入结构体解析&#xff1a; 可以看到&#xff0c;FETHA_OC了也就是A桥上管过流了&#xff1b; 检查一下硬件看看&#xff1…

【git】git update-index --assume-unchanged(不改动.gitignore实现忽略文件)

文章目录 原因分析&#xff1a;添加忽略文件(取消跟踪)的命令&#xff1a;取消忽略文件(恢复跟踪)的命令&#xff1a;查看已经添加了忽略文件(取消跟踪)的命令&#xff1a; 原因分析&#xff1a; 已经维护的项目&#xff0c;文件已经被追踪&#xff0c;gitignore文件不方便修…

天梯算法Day1整理

Nanami and Arithmetic Sequence 题面 思路 炸鱼题 只有n1的时候&#xff0c;只有一个等差数列&#xff1b; 其余时候&#xff0c;都是都有无数个等差数列。 代码 #include <iostream> using namespace std;int main() {int t, n;cin >> t;while (t--) {cin…

如何使用淘宝客?

1.定义&#xff1a;是一种按成交计费的推广工具&#xff0c;由淘宝客帮助商家推广商品&#xff0c;买家通过推广链接进入完成交易后&#xff0c;商家按照设置佣金支付给淘宝客费用。 2.优势&#xff1a; &#xff08;1&#xff09;展示、点击全免费。 &#xff08;2&#xf…

防御保护---防火墙双机热备直路部署(上下三层接口)

防御保护---防火墙双机热备直路部署&#xff08;上下三层接口&#xff09; 一、根据网段划分配置IP地址和安全区域二、配置动态路由OSPF三、配置双机热备四、测试&#xff1a;4.1 测试一&#xff1a;查看状态和路由器路由表&#xff08;双机热备&#xff09;前后对比4.2 测试二…

Ant-design-vue(v4.1.1) 创建并初始化前端项目

前提&#xff1a; 先安装 node.js (安装node.js后&#xff0c;在安装目录下的node-modles下会有一个 npm) 直接官网下载&#xff0c;直接点击安装&#xff0c;不勾选tools&#xff0c;选非c盘&#xff08;之后会用npm来下载东西&#xff09; 验证安装是否成功 cmd : node -v …