数据结构--《二叉树》

二叉树

1、什么是二叉树

二叉树(Binar Tree)是n(n>=0)个结点的优先集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两颗互不相交的、分别称为根结点的左子树和右子树的二叉树构成。

这里给张图,能更直观的感受二叉树:

  2、二叉树的特点

从上图可以看出二叉树的几个特点:

  1. 二叉树不存在度大于2的结点,每个结点最多有两颗子树;
  2. 左子树和右子树是有顺序的,次序不能颠倒;
  3. 即使树中的某个结点只有一颗子树,那也要区分它是左子树还是右子树。

讲到这那就不得不提及二叉树的五种基本形态:

  1. 空二叉树;
  2. 只有一个根节点;
  3. 根结点只有左子树;
  4. 根结点只有右子树;
  5. 根结点既有左子树又有右子树。

 

如下图所示,这棵树就不符合二叉树的条件,所以它就不是一颗二叉树。

 

3、几种特殊的二叉树

  1. 斜树:顾名思义,斜树一定是要斜的,但是往哪斜是有讲究的。所有结点只有左子树的二叉树叫左斜树。所有结点只有右子树的二叉树叫右斜树。这两者统称为斜树。
  2. 满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
  3. 完全二叉树:完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树而引出来的。对于深度为K的,有n个结点的二叉树,当且仅当其每一个结点都与深度为K的满二叉树中编从1n的结点一一对应时称之为完全二叉树。 要注意的是满二叉树是一种特殊的完全二叉树。

 

4、二叉树的性质

4.1 满二叉树的性质

  1. 叶子只能出现在最下一层。出现在其他层就不可能达到平衡;
  2. 非叶子节点的度一定是2,否则就是“缺胳膊少腿”了;
  3. 在同样深度的二叉树中,满二叉树的结点个数最多,叶子最多。

4.2 完全二叉树的性质

  1. 叶子结点只能出现在最下两层;
  2. 最下层的叶子一定集中在左部连续位置;
  3. 倒数两层,若有叶子结点,一定都在右部连续位置;
  4. 如果结点度为1,则该结点只有左孩子,即不存在只有右孩子的情况;
  5. 同样结点数的二叉树,完全二叉树的深度最小。

4.3 二叉树的性质

  1. 若规定根节点的层数为 1 ,则一棵非空二叉树的 i 层上最多有2^(i-1) 个结点.
  2. 若规定根节点的层数为1,则深度为h的二叉树的最大结点数是2^h - 1.
  3. 若规定根节点的层数为 1 ,具有 n 个结点的满二叉树的深度 h= log2(n+1). (ps:是log 2 为底,n+1 为对数 ).
  4. 对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对 于序号为i的结点有:
    1. i>0 i 位置节点的双亲序号: (i-1)/2 i=0 i 为根节点编号,无双亲节点
    2. 2i+1<n ,左孩子序号: 2i+1 2i+1>=n 否则无左孩子
    3. 2i+2<n ,右孩子序号: 2i+2 ,2i+2>=n否则无右孩子
  5. 对任何一棵二叉树, 如果度为 0 其叶结点个数为n0  , 度为 2 的分支结点个数为n2  , 则有 n0=n2 + 1.

5、现实中的二叉树

6、二叉树的存储结构

二叉树一般可以使用两种存储结构,一种是顺序存储结构,另一种则是链式存储结构。 

6.1 顺序存储结构

二叉树的顺序存储结构计算用一个一维数组存储二叉树中的结点。一般使用数组只适合表示完全二叉树,因为不是完全二叉树会有空间的浪费。而现实中使用中只有堆才会使用数组来存储。

6.2 链式存储结构

二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所 在的链结点的存储地址 。链式结构又分为二叉链和三叉链。

 

typedef int BTDataType;
// 二叉链
struct BinaryTreeNode
{struct BinTreeNode* _pLeft; // 指向当前节点左孩子struct BinTreeNode* _pRight; // 指向当前节点右孩子BTDataType _data; // 当前节点值域
}
// 三叉链
struct BinaryTreeNode
{struct BinTreeNode* _pParent; // 指向当前节点的双亲struct BinTreeNode* _pLeft; // 指向当前节点左孩子struct BinTreeNode* _pRight; // 指向当前节点右孩子BTDataType _data; // 当前节点值域
};

 

7、二叉树的顺序存储结构

普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结 构存储。现实中我们通常把堆 ( 一种二叉树 ) 使用顺序结构的数组来存储,需要注意的是这里的堆和操作系统 虚拟进程地址空间中的堆是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

7.1 堆的概念和结构

如果有一个关键码的集合 K = { k0 ,k1 ,k2 , ,kn-1},把它的所有元素按完全二叉树的顺序存储方式存储 在一个一维数组中,并满足: ki<=k2i+2 且 ki<=k2i+1 (ki >=k2i+1 且 ki>=k2i+2 ) i = 0, 1, 2…,则称为小堆 ( 或大堆 ) 。将根节点最大的堆叫做最大堆或大根堆,根节点最小的堆叫做最小堆或小根堆。
堆的性质
堆中某个节点的值总是不大于或不小于其父节点的值;
堆总是一棵完全二叉树。

 

 

7.2 堆的实现

 实现堆的接口函数:
 

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
#include<time.h>
#include<string.h>typedef int HPDataType;
typedef struct Heap
{//数组存储HPDataType* a;	//数组int size;	//数据的个数int capacity;	//数组长度
}HP;//初始化
void HeapInit(HP* php);//释放空间
void HeapDestory(HP* php);//插入数据
void HeapPush(HP* php, HPDataType x);//打印数据
void HeapPrint(HP* php);//删除数据
void HeapPop(HP* php);//获取第一个数据
HPDataType HeapTop(HP* php);//判断是否为空
bool HeapEmpty(HP* php);

函数的具体实现

#define _CRT_SECURE_NO_WARNINGS 1
#include"Heap.h"//初始化
void HeapInit(HP* php)
{assert(php);php->a = NULL;php->size = php->capacity = 0;
}//释放空间
void HeapDestory(HP* php)
{assert(php);free(php->a);php->a = NULL;php->size = php->capacity = 0;
}//交换数据
void Swap(HPDataType* x, HPDataType* y)
{HPDataType tmp = *x;*x = *y;*y = tmp;
}//结点向上调整 -- 小堆
void AdJustUp(HPDataType* a, int child)
{int parent = (child - 1) / 2;//循环判定条件为孩子结点下标大于0while (child > 0){	//如果孩子结点值小于父亲节点就相互交换if (a[child] > a[parent]){Swap(&a[child], &a[parent]);child = parent;parent = (parent - 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 + 1] > a[child]){++child;}if (a[child] > a[parent]){Swap(&a[child], &a[parent]);//继续向下调整parent = child; child = 2 * parent + 1;}else{break;}}
}//插入数据
void HeapPush(HP* php, HPDataType x)
{assert(php);//扩容if (php->capacity == php->size){int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;HPDataType* tmp = (HPDataType*)realloc(php->a, sizeof(HPDataType) * newcapacity);if (tmp == NULL){perror("realloc fail");exit(-1);}php->a = tmp;php->capacity = newcapacity;}php->a[php->size] = x;php->size++;//插入新元素后,要使原来的堆还是小堆,就得向上调整AdJustUp(php->a , php->size-1);
}//打印数据
void HeapPrint(HP* php)
{assert(php);for (int i = 0; i < php->size; i++){printf("%d ", php->a[i]);}
}//删除数据
void HeapPop(HP* php)
{assert(php);assert(php->size > 0);//交换第一个和最后一个数据Swap(&php->a[0], &php->a[php->size - 1]);--php->size;AdJustDown(php->a, php->size, 0);
}//获取第一个数据
HPDataType HeapTop(HP* php)
{assert(php);assert(php->size > 0);return php->a[0];
}//判断是否为空
bool HeapEmpty(HP* php)
{assert(php);return php->size == 0;
}

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

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

相关文章

GDPU JavaWeb mvc模式

搭建一个mvc框架的小实例。 简易计算器 有一个名为inputNumber.jsp的页面提供一个表单&#xff0c;用户可以通过表单输入两个数和运算符号提交给Servlet控制器&#xff1b;由名为ComputerBean.java生成的JavaBean负责存储运算数、运算符号和运算结果&#xff0c;由名为handleCo…

简单好用的文本识别方法--付费的好用,免费的更有性价比-记笔记

文章目录 先说付费的进入真题&#xff0c;免费的来喏&#xff01;PixPin微信 先说付费的 直达网址!!! 进入真题&#xff0c;免费的来喏&#xff01; PixPin 商店里就有 使用示例&#xff1a; 可以看到&#xff1a;贴在桌面上的图片可以复制图片中的文字&#xff0c;真的很…

Springboot+Vue+ElementUI开发前后端分离的员工管理系统01--系统介绍

项目介绍 springboot_vue_emp是一个基于SpringbootVueElementUI实现的前后端分离的员工管理系统 功能涵盖&#xff1a; 系统管理&#xff1a;用户管理、角色管理、菜单管理、字典管理、部门管理出勤管理&#xff1a;请假管理、考勤统计、工资发放、工资统计、离职申请、个人资…

8.Redis之hash类型

1.hash类型的基本介绍 哈希表[之前学过的所有数据结构中,最最重要的] 1.日常开发中,出场频率非常高. 2.面试中,非常重要的考点, Redis 自身已经是键值对结构了Redis 自身的键值对就是通过 哈希 的方式来组织的 把 key 这一层组织完成之后, 到了 value 这一层~~ value 的其中…

最重要的时间表示,柯桥外贸俄语小班课

в第四格 1、与表示“钟点”的数词词组连用 例&#xff1a; в шесть часов утра 在早上六点 в пять тридцать 在五点半 2、与表示“星期”的名词连用 例&#xff1a; в пятницу 在周五 в следующий понедельник …

String类为什么设计成不可变的?

目录 缓存 安全性 线程安全 hashCode缓存 性能 其实这个问题我们可以通过缓存、安全性、线程安全和性能几个维度去解析。 缓存 字符串是Java最常用的数据结构&#xff0c;我们都知道字符串大量创建是非常耗费资源的&#xff0c;所以Java中就将String设计为带有缓存的功能…

【python】python tkinter 计算器GUI版本(模仿windows计算器 源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

17.分类问题

机器学习分类问题详解与实战 介绍 在机器学习中&#xff0c;分类问题是一类常见的监督学习任务&#xff0c;其目标是根据输入特征将数据样本划分为预先定义的类别之一。分类问题广泛应用于各个领域&#xff0c;如图像识别、自然语言处理、金融风险评估等。本文将详细介绍机器…

Spring Cloud 项目中使用 Swagger

Spring Cloud 项目中使用 Swagger 关于方案的选择 在 Spring Cloud 项目中使用 Swagger 有以下 4 种方式&#xff1a; 方式一 &#xff1a;在网关处引入 Swagger &#xff0c;去聚合各个微服务的 Swagger。未来是访问网关的 Swagger 原生界面。 方式二 &#xff1a;在网关处引…

RedHat9 | DNS剖析-配置辅助DNS服务器

一、实验环境 1、辅助域名DNS服务器 DNS通过划分为若干个区域进行管理&#xff0c;每一个区域由1台或多台DNS服务器负责解析&#xff0c;如果仅仅采用1台DNS服务器&#xff0c;在DNS服务器出现故障后&#xff0c;用户将无法完成解析。 辅助DNS服务器的优点 容灾备份&#x…

区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测

区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测 目录 区间预测 | Matlab实现DNN-KDE深度神经网络结合核密度估计多置信区间多变量回归区间预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现DNN-KDE深度神经网络结合…

MySQL数据处理增删改

数据处理增删改DML 由于约束&#xff0c;以下操作都有可能执行失败&#xff08;后面讲约束&#xff09; 插入数据 INSERT 基础添加&#xff1a;VALUES 值的顺序必须和表中字段顺序相同 INSERT INTO class VALUES(1,王小,10); 向指定字段添加&#xff1a; 值的顺序和指定…

MT7628原厂Uboot修改交互串口

工作中&#xff0c;遇到用户用Skylab的SKW92A模组&#xff0c;在参考设计时&#xff0c;将UART接口预留错的情况&#xff0c;对于这种情况&#xff0c;需要将原厂SDK默认的交互串口UART0&#xff0c;改为UART1。在开发过程中&#xff0c;经常需要在Uboot阶段升级固件&#xff0…

【Linux部署】【pig前端部署】Linux安装- docker/docker-compose/nginx (使用docker优雅部署nginx)

&#x1f338;&#x1f338; Linux安装- docker/docker-compose/nginx 优雅部署 &#x1f338;&#x1f338; 一、一键安装jdk yum install -y java-1.8.0-openjdk.x86_64验证 二、安装docker yum list docker-ce --showduplicates | sort -rsudo yum install -y yum-utils …

LabVIEW波纹补偿器无线监测系统

LabVIEW波纹补偿器无线监测系统 在石油化工、冶金及电力等行业中&#xff0c;波纹补偿器作为一种重要的补偿性元件&#xff0c;其安全稳定的运行对管道输送系统的可靠性至关重要。开发了一种基于LabVIEW的波纹补偿器无线监测系统&#xff0c;通过实时监测波纹补偿器的工作状态…

嵌入式单片机寄存器操作与实现方法

大家好,今天给大家分享一下,单片机中寄存器该如何操作与实现。 “芯片里面的寄存器访问方式一般是: 1.可使用地址访问,2.可使用指令访问,3.不可访问” 第一:挂载到内存地址总线上了的 挂载到内存地址总线上了的,可以使用分配到的地址访问 如下是STM32单片机存储器映像…

单条16g和双条8g哪个好

单条16g和双条8g各有优劣,具体选择要根据个人需求和电脑配置来决定。 以下是一些参考信息: •单条16g内存的价格比双条8g内存的价格低,而且16g的内存容量大,一条内存十分的方便。 •两条8g内存可以组成双通道,电脑运行速度要快一些。 •对于普通使用电脑的人群与热衷于…

Sourcetree安装教程及使用

1 Sourcetree介绍 Sourcetree是一款免费的Git图形化客户端&#xff0c;它由Atlassian开发&#xff0c;提供了跨平台的支持&#xff0c;可运行在Windows和Mac操作系统上。Sourcetree可以让开发者更方便地使用Git来管理代码&#xff0c;不需要在命令行中输入复杂的Git命令&#x…

asp.net core接入prometheus2-自定义指标

前提 了解一下asp.net core接入prometheus快速入门 https://blog.csdn.net/qq_36437991/article/details/139064138 新建.net 8空web项目 安装下面三个包 <PackageReference Include"OpenTelemetry.Exporter.Prometheus.AspNetCore" Version"1.8.0-rc.1&…

druid 1.2.14,application.yaml配置文件中,如何进行数据库加密配置

步骤一&#xff1a;先生成加密的密码&#xff1a; 步骤二&#xff1a;配置application.yaml文件&#xff1a; spring:datasource:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourcedruid:username: rootpassword: aPJ35saFz6ASmnmNt…