首页 > 其他分享 >完全二叉树与堆

完全二叉树与堆

时间:2024-09-04 23:52:18浏览次数:10  
标签:void 完全 HPDataType 二叉树 child php 节点

目录

认识堆的简单结构:

二叉树:

完全二叉树:

堆:

大堆:

小堆:

完全二叉树可以由顺序表实现:

堆的常用接口(我们实现一个大堆):

方便交换的函数:

堆的初始化:

堆的销毁:

堆插入:

堆顶数据的删除:

取堆顶数据:

堆的判空:

向上调整:

向下调整:


认识堆的简单结构:

二叉树:

二叉树是一种每个节点最多有两个子节点的数据结构。每个节点包含一个值和指向两个子节点的指针,通常分别称为左子节点和右子节点。

完全二叉树:

完全二叉树是一种特殊类型的二叉树,除了最后一层以外的每一层都被完全填满,最后一层的节点都集中在左边。(完全二叉树可以由顺序表实现,一会我会详细地进行讲解)

堆:

堆是一种完全二叉树。

大堆:

在“大堆”中,每个节点的值都大于或等于其子节点的值。也就是说,根节点的值是整个堆中的最大值。

小堆:

在“小堆”中,每个节点的值都小于或等于其子节点的值。也就是说,根节点的值是整个堆中的最小值。

完全二叉树可以由顺序表实现:

完全二叉树中:

1.假设一个根节点的下标为i,则它的两个子节点的下标分别为2i+1和2i+2,。

2.假设一个子节点的下标为i,则它所对应的根节点的下标为(i-1)/2。

正因为完全二叉树中根节点与子节点的下标之间存在某种特殊关系,所以完全二叉树可以由顺序表实现。

堆的常用接口(我们实现一个大堆):

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>


typedef int HPDataType;

typedef struct Heap
{
	HPDataType* a;
	int size;
	int capacity;
}HP;

//方便交换的函数
void Swap(HPDataType* p1, HPDataType* p2);
//向上调整
void AdjustUp(HPDataType* a, int child);
//向下调整
void AdjustDown(HPDataType* a, int n, int parent);
//堆的初始化
void HPInit(HP* php);
//堆的销毁
void HPDestroy(HP* php);
//堆插入
void HPPush(HP* php, HPDataType x);
//堆顶数据的删除
void HPPop(HP* php);
// 取堆顶的数据
HPDataType HPTop(HP* php);
// 堆的判空
bool HPEmpty(HP* php);

方便交换的函数:

因为我们在大堆中插入删除,会经常做数据交换,不然无法保证后来的堆还是个大堆,所以我们单独写出一个Swap函数,以便交换数据。

//方便交换的函数
void Swap(HPDataType* p1, HPDataType* p2)
{
	HPDataType  tmp = *p1;
	*p1 = *p2;
	*p2 = tmp;
}

堆的初始化:

//堆的初始化
void HPInit(HP* php)
{
	php->a = (HPDataType*)malloc(4 * sizeof(HPDataType));
	php->size = 0;
	php->capacity = 4;
}

堆的销毁:

//堆的销毁
void HPDestroy(HP* php)
{
	free(php->a);
	php->a = NULL;
	php->size = php->capacity = 0;
}

堆插入:

void HPPush(HP* php, HPDataType x)
{
	if (php->capacity == php->size)
	{
		int newcapacity = 2 * php->capacity;
		php->a = (HPDataType*)realloc(php->a, newcapacity * sizeof(HPDataType));
		php->capacity = newcapacity;
	}
	php->a[php->size] = x;
	php->size++;
	AdjustUp(php->a,php->size-1);
}

堆插入,可以先在堆尾插入,插入后再把堆尾数据向上调整即可。向上调整函数稍后会讲到。

堆顶数据的删除:

//堆顶数据的删除
void HPPop(HP* php)
{
	Swap(&php->a[0], &php->a[php->size - 1]);
	php->size--;

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

}

要删除堆顶数据,我们可以先把堆顶数据和堆尾数据进行交换,然后进行删除,删除后将之后的堆顶数据向下调整即可。向下调整稍后会讲到。

取堆顶数据:

// 取堆顶的数据
HPDataType HPTop(HP* php)
{
	return php->a[0];
}

堆的判空:

// 堆的判空
bool HPEmpty(HP* php)
{
	return  !(php->size);
}

向上调整:

向上调整的接口主要接收顺序表的头指针,和想要向上调整的数据的下标。

//向上调整
void AdjustUp(HPDataType* 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;
	}
}

向上调整的主要思路是孩子节点和父亲节点去比大小,如果孩子比父亲大就要实行一次交换。就这样,孩子和父亲不断往完全二叉树的上方走、并且不断地进行比较和交换。最终就能实现此数据结构还是个大堆。

向下调整:

//向下调整
void AdjustDown(HPDataType* a, int n, int parent)
{
	int child = 2 * parent + 1;
	while (child < n)
	{
		if (child + 1 < n && a[child] < a[child + 1])
		{
			child++;
		}
		if (a[parent] < a[child])
		{
			Swap(&a[parent], &a[child]);
			parent = child;
			child = 2 * parent + 1;
		}
	}
}

向下调整过程中,先要比两个孩子的大小,挑出较大的那个孩子,然后父亲再和孩子比,如果父亲比孩子小,那么就交换父亲和孩子。就这样,孩子和父亲不断往完全二叉树的下方走、并且不断地进行比较和交换。最终就能实现此数据结构还是个大堆。

标签:void,完全,HPDataType,二叉树,child,php,节点
From: https://blog.csdn.net/GGbond665/article/details/141874675

相关文章

  • LeeCode-104. 二叉树的最大深度
    要求给定一个二叉树root,返回其最大深度。二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。如下图所示的二叉树最大深度为5.解题思路与94题类似,采用递归调用遍历子节点。在基本结构中,节点的最大深度等于根深度(1)加上左右较大深度,左右较大的深度可以......
  • LeeCode-94. 二叉树的中序遍历
    基本概念二叉树二叉树的结构如上图所示,由一系列左-中-右节点组成的树状数据结构,其基本结构如下所示,由一个中间节点向左右分叉成两个节点,故称二叉树。中序遍历看二叉树基本的结构左-中-右三个节点,中间为Root,左边为Left,右边为Right。按顺序排列的话有C(3,2)=6种,其中左右,......
  • 完全删除或卸载PHPnow环境配置包(图解)
    PHPnow是PHP平台很方便的搭建工具聚,但俗话说的好,轻声容易送神难。PHPnow不是常规的安装软件,所以他没有像一般安装在Windows下的软件中一样的卸载程序。如果用户直接把他的安装目录删除,系统是拒绝的。有些朋友可能使用phpnow久了,觉得它有庞大,于是乎卸载phpnow,这里分享一下phpnow卸......
  • C++ 数据结构——二叉树(最最最最最实用的二叉树教程)
    本文章以实用为主,所以不多废话直接开整本文所介绍的二叉树是最基础的二叉树,不是二叉搜索树,也不是平衡二叉树,就基本的二叉树若需要Python版,请跳转到 Python数据结构——二叉树(最最最最最实用的二叉树教程)二叉树的构建二叉树为一个父节点连接到两个子节点,若还要加入新的......
  • 力扣-968监控二叉树(Java贪心详细题解)
    题目链接:968.监控二叉树-力扣(LeetCode)前情提要:本题是一道名副其实的hard题目,他考察二叉树和贪心的综合运用能力。所以我们不仅要会贪心还要会二叉树的一些知识,如果没有写二叉树类型的题目,建议大家该题可以放放,去刷其他的题目。因为本人最近都来刷贪心类的题目所以该......
  • 博弈论简述 第二章 完全信息动态博弈 自用整理中
    持续更新中博弈论简述系列主要参考本校授课老师的PPT,相当于把老师的PPT简单过了一遍,加上自己的理解,但是个人觉得PPT内容系统结构不太行,后面有时间再慢慢调整。没有什么技术性的内容,主要是简述。后面准备开一个系列,认真研读一下一些技术性的内容。一、完美信息动态博弈1、......
  • 博弈论简述 第一章 完全信息静态博弈 自用整理中
    持续更新中博弈论简述系列主要参考本校授课老师的PPT,相当于把老师的PPT简单过了一遍,加上自己的理解,但是个人觉得PPT内容系统结构不太行,后面有时间再慢慢调整。没有什么技术性的内容,主要是简述。后面准备开一个系列,认真研读一下一些技术性的内容。一、博弈的标准式和纳什均......
  • 推断二叉树(递推)
    已知前序中序求后序#include<cstring>#include<cstdio>#include<iostream>usingnamespacestd;voidbinary_tree(stringmid,stringpre){ if(mid.size()>0){ charch=pre[0]; intcur=mid.find(ch); binary_tree(mid.substr(0,cur),pre......
  • Day14|第六章 二叉树 part02| 226.翻转二叉树| 101. 对称二叉树| 104.二叉树的最大深
    226.翻转二叉树(递归只能前序或者后序,中序不行)classSolution{publicTreeNodeinvertTree(TreeNoderoot){if(root==null)returnnull;swap(root);invertTree(root.left);invertTree(root.right);//swap(root);......
  • 算法与数据结构——二叉树数组表示
    二叉树数组表示在链表表示下,二叉树的存储单元为节点TreeNode,节点之间通过指针相连接。同前面的队列或栈,二叉树同样可以使用数组来表示。表示完美二叉树给定一棵完美二叉树,我们将所有节点按照层序遍历的顺序存储在一个数组中,则每个节点都对应唯一的数组索引。按照层序遍历的特......