数据结构与算法之美学习笔记:23 | 二叉树基础(上):什么样的二叉树适合用数组来存储?

目录

  • 前言
  • 树(Tree)
  • 二叉树(Binary Tree)
  • 二叉树的遍历
  • 解答开篇 & 内容小结

前言

在这里插入图片描述
本节课程思维导图:
在这里插入图片描述
前面我们讲的都是线性表结构,栈、队列、链表等等。今天我们讲一种非线性表结构,树。问题:二叉树有哪几种存储方式?什么样的二叉树适合用数组来存储?

树(Tree)

在这里插入图片描述

“树”这种数据结构真的很像我们现实生活中的“树”,这里面每个元素我们叫做“节点”;用来连接相邻节点之间的关系,我们叫做“父子关系”。
A 节点就是 B 节点的父节点,B 节点是 A 节点的子节点。B、C、D 这三个节点的父节点是同一个节点,所以它们之间互称为兄弟节点。我们把没有父节点的节点叫做根节点,也就是图中的节点 E。我们把没有子节点的节点叫做叶子节点或者叶节点,比如图中的 G、H、I、J、K、L 都是叶子节点。
关于“树”,还有三个比较相似的概念:高度(Height)、深度(Depth)、层(Level)。它们的定义是这样的:
在这里插入图片描述
我举个例子说明一下,你一看应该就能明白。
在这里插入图片描述
树这种数据结构的高度也是一样,从最底层开始计数,并且计数的起点是 0。
树这种数据结构的深度也是类似的,从根结点开始度量,并且计数起点也是 0。
“层数”跟深度的计算类似,不过,计数起点是 1,也就是说根节点位于第 1 层。

二叉树(Binary Tree)

二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只有左子节点,有的节点只有右子节点。
在这里插入图片描述
其中,编号 2 的二叉树中,叶子节点全都在最底层,除了叶子节点之外,每个节点都有左右两个子节点,这种二叉树就叫做满二叉树。
编号 3 的二叉树中,叶子节点都在最底下两层,最后一层的叶子节点都靠左排列,并且除了最后一层,其他层的节点个数都要达到最大,这种二叉树叫做完全二叉树。
为什么偏偏把最后一层的叶子节点靠左排列的叫完全二叉树?如果靠右排列就不能叫完全二叉树了吗?这个定义的由来或者说目的在哪里?
如何表示(或者存储)一棵二叉树?想要存储一棵二叉树,我们有两种方法,一种是基于指针或者引用的二叉链式存储法,一种是基于数组的顺序存储法。
我们先来看比较简单、直观的链式存储法。从图中你应该可以很清楚地看到,每个节点有三个字段,其中一个存储数据,另外两个是指向左右子节点的指针。我们只要拎住根节点,就可以通过左右子节点的指针,把整棵树都串起来。这种存储方式我们比较常用。大部分二叉树代码都是通过这种结构来实现的。
在这里插入图片描述
我们再来看,基于数组的顺序存储法。我们把根节点存储在下标 i = 1 的位置,那左子节点存储在下标 2 * i = 2 的位置,右子节点存储在 2 * i + 1 = 3 的位置。以此类推,B 节点的左子节点存储在 2 * i = 2 * 2 = 4 的位置,右子节点存储在 2 * i + 1 = 2 * 2 + 1 = 5 的位置。
在这里插入图片描述
我来总结一下,如果节点 X 存储在数组中下标为 i 的位置,下标为 2 * i 的位置存储的就是左子节点,下标为 2 * i + 1 的位置存储的就是右子节点。反过来,下标为 i/2 的位置存储就是它的父节点。通过这种方式,我们只要知道根节点存储的位置(一般情况下,为了方便计算子节点,根节点会存储在下标为 1 的位置),这样就可以通过下标计算,把整棵树都串起来。

我刚刚举的例子是一棵完全二叉树,所以仅仅“浪费”了一个下标为 0 的存储位置。如果是非完全二叉树,其实会浪费比较多的数组存储空间。你可以看我举的下面这个例子。
在这里插入图片描述
所以,如果某棵二叉树是一棵完全二叉树,那用数组存储无疑是最节省内存的一种方式。因为数组的存储方式并不需要像链式存储法那样,要存储额外的左右子节点的指针。这也是为什么完全二叉树会单独拎出来的原因,也是为什么完全二叉树要求最后一层的子节点都靠左的原因。

二叉树的遍历

经典的方法有三种,前序遍历、中序遍历和后序遍历。其中,前、中、后序,表示的是节点与它的左右子树节点遍历打印的先后顺序。

  1. 前序遍历是指,对于树中的任意节点来说,先打印这个节点,然后再打印它的左子树,最后打印它的右子树。
  2. 中序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它本身,最后打印它的右子树。
  3. 后序遍历是指,对于树中的任意节点来说,先打印它的左子树,然后再打印它的右子树,最后打印这个节点本身。

在这里插入图片描述
实际上,二叉树的前、中、后序遍历就是一个递归的过程。比如,前序遍历,其实就是先打印根节点,然后再递归地打印左子树,最后递归地打印右子树。

void preOrder(Node* root) {if (root == null) return;print root // 此处为伪代码,表示打印root节点preOrder(root->left);preOrder(root->right);
}void inOrder(Node* root) {if (root == null) return;inOrder(root->left);print root // 此处为伪代码,表示打印root节点inOrder(root->right);
}void postOrder(Node* root) {if (root == null) return;postOrder(root->left);postOrder(root->right);print root // 此处为伪代码,表示打印root节点
}

从我前面画的前、中、后序遍历的顺序图,可以看出来,每个节点最多会被访问两次,所以遍历操作的时间复杂度,跟节点的个数 n 成正比,也就是说二叉树遍历的时间复杂度是 O(n)。

解答开篇 & 内容小结

关于树,有几个比较常用的概念你需要掌握,那就是:根节点、叶子节点、父节点、子节点、兄弟节点,还有节点的高度、深度、层数,以及树的高度。
我们平时最常用的树就是二叉树。二叉树的每个节点最多有两个子节点,分别是左子节点和右子节点。二叉树中,有两种比较特殊的树,分别是满二叉树和完全二叉树。满二叉树又是完全二叉树的一种特殊情况。
二叉树既可以用链式存储,也可以用数组顺序存储。数组顺序存储的方式比较适合完全二叉树,其他类型的二叉树用数组存储会比较浪费存储空间。除此之外,二叉树里非常重要的操作就是前、中、后序遍历操作,遍历的时间复杂度是 O(n)。

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

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

相关文章

WebGoat通关攻略之 SQL Injection (intro)

SQL Injection (intro) 1. What is SQL? 本题练习SQL查询语句,就是写一句SQL获取叫Bob Franco所在的department SELECT department FROM employees WHERE first_name Bob AND last_name Franco成功通关! 2. Data Manipulation Language (DML) 本题…

安卓毕业设计:基于安卓android微信小程序的超市购物系统

运行环境 开发语言:Java 框架:ssm JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包&a…

喜报 | 思码逸 DevInsight 通过DaoCloud兼容性互认证

近日,北京思码逸科技有限公司(简称:思码逸)的 Devlnsight 一站式研发效能度量平台与上海道客网络科技有限公司(简称:DaoCloud)的 DaoCloud Enterprise 云原生操作系统 V5.0,经双方联…

数据结构:lambda表达式

基本概念 语法 // 1. 不需要参数,返回值为 2 () -> 2 // 2. 接收一个参数(数字类型),返回其2倍的值 x -> 2 * x // 3. 接受2个参数(数字),并返回他们的和 (x, y) -> x y // 4. 接收2个int型整数,返回他们的乘积 (int x, int y) -> x * y // 5. 接受一个 string 对…

配置中心

服务配置中心介绍 首先我们来看一下,微服务架构下关于配置文件的一些问题: 1. 配置文件相对分散。 在一个微服务架构下,配置文件会随着微服务的增多变的越来越多,而且分散 在各个微服务中,不好统一配置和管理。 2. 配置文件无…

ACREL DC energy meter Application in Indonesia

安科瑞 华楠 Abstract: This article introduces the application of Acrel DC meters in base station in Indonesia.The device is measuring current,voltage and energy together with hall current sensor. 1.Project Overview This company is located in Indonesia a…

substring-after用法

substring-after:函数返回一个字符串,该字符串是给定子字符串后给定字符串的其余部分。 #句法 substring-after( haystack ,needle) haystack:要评估的字符串。该字符串的一部分将被返回。 needle:要搜索的子字符串。needle在h…

SqlServer_idea连接问题

问题描述: sqlServer安装之后可以使用navicat进行连接idea使用账户密码进行登录连接失败 问题解决: 先使用sqlServer管理工具进行登录 使用window认证连接修改账户密码 启用该登录名 这时idea还是无法连接,还需要如下配置 打开sqlserve…

140.【鸿蒙OS开发-01】

鸿蒙开发 (一)、初识鸿蒙1.初识鸿蒙(1).移动通讯技术的发展(2).完整的鸿蒙开发 (二)、鸿蒙系统介绍1.鸿蒙系统的官方定义(1).鸿蒙操作系统概述(2).鸿蒙的生态 2.鸿蒙系统的特点3.鸿蒙和安卓的对比4.鸿蒙开发的发展前景 (三)、鸿蒙开发准备工作1.鸿蒙OS的完整开发流程2.注册并实…

哈希表HashTable

散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。 哈希表中关键码就是数组的索引下标,然后通过下标直接访问数组中的元素,复杂度O(1) 哈希表本质…

Idea2023 Springboot web项目正常启动,页面展示404解决办法

Idea2023 Springboot web项目正常启动,页面展示404解决办法 问题: 项目启动成功,但是访问网页,提示一直提示重定向次数过多,404 解决方法 在IDEA的Run/Debug Configurations窗口下当前的Application模块的Working directory中添…

JS-项目实战-新增水果库存功能实现

1、fruit.js function $(name) {if (name) {//假设name是 #fruit_tblif (name.startsWith("#")) {name name.substring(1); //fruit_tblreturn document.getElementById(name);} else {return document.getElementsByName(name); //返回的是NodeList类型}} }//当…

浅谈电动汽车充电桩设计与应用研究

安科瑞 华楠 摘要:目前,随着我国社会经济的快速发展,我国的各个领域都取得了突破性的发展,尤其是在电动汽车充电桩的设计方法,新型的电动汽车充电桩设计已经广泛的受到了人民群众的青睐与认可,而这种发展前…

【网络编程】简述TCP通信程序,三次握手,四次挥手

文章目录 🎄TCP通信程序⭐打印字符串✨中文乱码问题🎈解决方法 🌺TCP三次握手🌺TCP四次挥手🛸其他 🎊专栏【网络编程】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 &#x1f386…

VC++添加包含目录

安装了QT;它带有很多例子; 新建一个工程,添加一个C++源文件,随便拷个例子的源码过来; 然后VS会提示头2个include语句出错; 因为找不到这两个头文件;这需要添加包含目录; 进入项目属性页;VC++目录 - 包含目录,它之前有2个系统的值;点击右侧的下拉箭头按钮,点…

基于Java GUI模拟银行自动取款机

一、课题描述 编写一个程序,模拟银行自动取款机的工作流程。主要功能如下所述: 当输入给定的卡号和密码(初始卡号为888888和密码为123456)时,系统能登录ATM柜员机系统,用户可以按照以下规则进行: 查询余额:初始余额为50000元 ATM取款:每次…

数据结构 栈与队列详解!!

一.栈 关于内存中的栈和数据结构中的栈是不同的,本章着重讲的是数据结构的栈。 这是一张关于栈的表达图。从图中可以看出栈很像是一副卡牌,发牌时只能从上取出,即出栈。 而入栈则是像你出牌后,要把你出的牌压在上一张出的牌上面。…

【算法基础】筛质数

文章目录 问题描述解决方法朴素筛法线性筛法 问题描述 给定一个正整数 n n n,请你求出 1 ∼ n 1∼n 1∼n 中质数的个数。 输入格式 共一行,包含整数 n。 输出格式 共一行,包含一个整数,表示 1∼n 中质数的个数。 数据范围 …

完美解决k8s master节点无法ping node节点中的IP或Service NodePort的IP

1、问题一 使用搭建好了K8S集群,先是node节点加入k8s集群时,用的内网IP,导致master节点无法操作node节点中的pod(这里的不能操作,指定是无法查看node节点中pod的日志、启动描述、无法进入pod内部,即 kubec…

【GCN】GCN学习笔记一

谱域图卷积 卷积 卷积定义离散空间的卷积 图卷积简介 卷积定理谱域图卷积实现思路如何定义图上的傅里叶变换拉普拉斯矩阵 (Laplacian Matrix)拉普拉斯矩阵的性质拉普拉斯矩阵的谱分解拉普拉斯矩阵与拉普拉斯算子 图傅里叶变换 图上的信号表示经典傅里叶变…