基础二叉树及其高频面试题

news2025/4/3 22:00:03

目录

一、树的概念及其结构

1.1 树的概念

1.2 树的相关概念

1.3 树的表示法

二、二叉树的概念及其结构

2.1 概念

2.2 特殊二叉树

2.3 二叉树的性质

2.4 二叉树的存储结构

顺序存储

链式存储

三、链式二叉树

3.1 遍历方式

深度优先遍历:DFS

层序遍历:BFS(广度优先遍历)

3.2 二叉树的创建和销毁

四、常见面试题


普通的二叉树其实在实际运用中并不能发挥出什么作用。但是它是我们学习后续的二叉搜索树、AVL树、红黑树等数据结构时必备的基础,常见的二叉树面试题中使用的基本上也是普通二叉树,所以学好普通二叉树也是十分重要的。

一、树的概念及其结构

1.1 树的概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它称为树,是因为它看起来像一棵倒挂的树,根部分朝上,叶子部分朝下。

特点:

1. 树有一个特殊的结点,称为根结点,根节点没有前驱结点

2. 除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1 <= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继

3. 树是递归定义的

注意:树形结构中,子树之间不能有交集,否则就不是树形结构
 

1.2 树的相关概念

1.3 树的表示法

树有很多种表示方式如:双亲表示法,孩子表示法、孩子双亲表示法以及孩子兄弟表示法等。

我们这里就简单的了解其中最常用的孩子兄弟表示法

typedef int DataType;
struct Node
{
    struct Node* _firstChild1; //第一个孩子结点
    struct Node* _pNextBrother; //指向其下一个兄弟结点
    DataType _data;
};

二、二叉树的概念及其结构

2.1 概念

二叉树是n(n>=0)个结点的有限集合,由一个根结点以及两棵互不相交,分别称为左子树和右子树的二叉树组成

2.2 特殊二叉树

1. 满二叉树:
一棵深度为h且有2^h - 1个结点的二叉树(即每层的结点数都达到最大值)

2. 完全二叉树:
除最后一层外,每层上的结点数都达到最大值,在最后一层上只缺少右边的若干结点
(对于深度为k的且有n个结点的二叉树,当且仅当其每一个结点与深度为k的满二叉树中编号从1到n的结点一一对应时,该二叉树被称为完全二叉树)
满二叉树是一种特殊的完全二叉树

2.3 二叉树的性质

1.每个结点最多有两棵子树,即二叉树不存在度大于2的结点

2.二叉树的子树有左右之分,其子树的次序不能颠倒(有序树)

3.在二叉树的第i层上至多有 2^(i-1) 个结点 (i>0)

4.深度为k的二叉树至多有 2^k - 1 个结点(k>0)

5.对于任何一棵二叉树,若度为2的结点树有m个,则叶子数n必为m+1(即n = m+1)

6.具有N个结点的满二叉树的深度为 以2为底(N+1)的对数

7.对于具有n个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有节点从0开始编号,则对于序号为i的结点有:
    (1)若i > 0,i位置结点的双亲序号: (i-1)/2        若i = 0,i为根节点编号,无双亲节点
    (2)若2i + 1 < n,i位置结点左孩子序号: 2i + 1    若2i + 1 >= n则无左孩子
    (3)若2i + 2 < n,i位置结点右孩子序号: 2i + 2    若2i + 2 >= n则无右孩子

2.4 二叉树的存储结构

顺序存储

利用数组存储,一般数组只适合表示完全二叉树(不是完全二叉树会有空间上的浪费),现实中使用中只有堆才会使用数组来存储
二叉树顺序存储在物理上是一个数组,在逻辑上是一个二叉树

具体可以看我的另一篇博客:

(10条消息) 堆结构的深度理解_GG_Bond19的博客-CSDN博客https://blog.csdn.net/GG_Bruse/article/details/127742947

链式存储

二叉树的链式存储结构是指用链表来表示一棵二叉树,即用链来指示元素之间的逻辑关系。
通常的方法:链表的每个结点由三个域组成,数据域和左右指针域(即二叉链)。

链式结构又分为二叉链(left和right)和三叉链(left、right和parent)

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; // 当前节点值域
}

三、链式二叉树

3.1 遍历方式

深度优先遍历:DFS

先序(根)遍历:        根 左子树 右子树 NLR    最符合深度优先
中序(根)遍历:        左子树 根 右子树 LNR
后序(根)遍历:        左子树 右子树 根 LRN

typedef char BTDataType;
struct BinaryTreeNode
{
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTDataType data;
};

void PrevOrder(struct BinaryTreeNode* root)//前序
{
	if (root == NULL) {
		printf("NULL ");
		return;
	}
	printf("%c ", root->data);
	PrevOrder(root->left);
	PrevOrder(root->right);
}

void InOrder(struct BinaryTreeNode* root)//中序
{
	if (root == NULL) {
		printf("NULL ");
		return;
	}  
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}

void PostOrder(struct BinaryTreeNode* root)//后序
{
	if (root == NULL) {
		printf("NULL ");
		return;
	}
	PostOrder(root->left);
	PostOrder(root->right);
	printf("%c ", root->data);
}

层序遍历:BFS(广度优先遍历)

设二叉树的根结点所在层数为1,层序遍历就是从所在二叉树的根结点出发,
首先访问第一层的树根结点,然后从左到右访问第二层上的结点,以此类推,从上到下,从左到右,逐层访问树的结点。

void LevelOrder(BinaryTreeNode* root)//层序遍历
{
	Queue q;
	QueueInit(&q);
	if (root != NULL) QueuePush(&q, root);
	while (!QueueIsEmpty(&q))
	{
		struct BinaryTreeNode* front = QueueFront(&q);
		QueuePop(&q);
		printf("%c ", front->data);
		if (front->left != NULL) QueuePush(&q, front->left);
		if (front->right != NULL) QueuePush(&q, front->right);
	}
	QueueDestory(&q);
}

思路: 利用队列完成非递归的层序遍历

1、首先将二叉树的根节点push到队列中,判断队列不为空,就输出队头的元素,
2、遍历过的节点出队列
3、判断节点如果有孩子,就将孩子push到队列中
4、循环以上操作,直到Tree == NULL。

3.2 二叉树的创建和销毁

通过前序遍历的数组来构建二叉树

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef char BTDataType;
typedef struct BinaryTreeNode {
	struct BinaryTreeNode* left;
	struct BinaryTreeNode* right;
	BTDataType data;
}BinaryTreeNode;

BinaryTreeNode* BuyNode(BTDataType x) {
	BinaryTreeNode* node = (BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));
	assert(node);
	node->data = x;
	node->left = node->right = NULL;
	return node;
}

BinaryTreeNode* CreateTree(char* str, int* pi) {
	if (str[*pi] == '#') {
		++(*pi);
		return NULL;
	}
	BinaryTreeNode* root = BuyNode(str[(*pi)++]);
	root->left = CreateTree(str, pi);
	root->right = CreateTree(str, pi);
	return root;
}

void InOrder(BinaryTreeNode* root) {
	if (root == NULL) return;
	InOrder(root->left);
	printf("%c ", root->data);
	InOrder(root->right);
}

void DestoryTree(BinaryTreeNode* root)//后序销毁
{
	if (root == NULL) return;
	DestoryTree(root->left);
	DestoryTree(root->right);
	free(root);
}
int main()
{
	char str[101] = { 0 };
	scanf("%s", str);

	int i = 0;
	BinaryTreeNode* root = CreateTree(str, &i);

	InOrder(root);

	DestoryTree(root);
	return 0;
}

四、常见面试题

未完

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

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

相关文章

【附源码】Python计算机毕业设计社区防疫信息管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Debian11中 Nginx1.22.1 php8.1.12 Mariadb10.5.15的安装

起因&#xff1a;我之前发的关于LEMP的搭建的文章&#xff0c;已经有3年9个月了&#xff0c;各个软件的版本更新了比较多。最主要的是&#xff0c;CentOS系统终止了&#xff0c;我也完全更换到了Debian系统之上。这里重新搭建了一下&#xff0c;主要是计划结合frp&#xff0c;构…

Vue | Vue.js 全家桶 Pinia状态管理

&#x1f5a5;️ Vue .js专栏&#xff1a;Node.js Vue.js 全家桶 Pinia状态管理 &#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; ✨ 个人主页&#xff1a;CoderHing的个人主页 &#x1f340; 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀…

[基础服务] [操作系统] 类Linux的文件和目录

&#x1f341;简介 在奔腾70年代的中美建交之际,UNIX 也逐渐展露头角(也有说是60年代末),十五年后Windows诞生了,又过了五年Linux横空出世三大主流操作系统直到现在呈现三足鼎立之势~ 出生时间是&#xff1a; UNIX(70年代初) > Windows(80年代中) > Linux (90年代初) 可以…

基于微信小程序的电影院票务系统设计与实现-计算机毕业设计源码+LW文档

小程序开发说明 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mav…

HCIP-Datacom OSPF进阶(二)最常用的路由协议 OSPF各种LSA作用详解

目录 OSPF路由计算&#xff1a; LSA头部信息&#xff1a; Router-LSA&#xff08;1类&#xff09;&#xff1a; 一类LSA&#xff1a; 一类LSA可以描述四种链路类型&#xff1a; Network-LSA&#xff08;2类&#xff09;&#xff1a; 二类&#xff1a; IR、ABR、ASBR是什…

【HTML实战】把专属于她的爱心代码放在自己的网站上是一种什么体验?

一、 写在前面的话 看多了李洵的炫酷爱心&#xff0c;今天来点不一样的爱心代码。需要李洵的炫酷爱心代码请看我的上一篇文章。 最近随着电视剧《点燃我温暖你》的火热播出&#xff0c;剧中帅气学霸李洵的炫酷爱心代码也迅速火出了圈&#xff0c;作为一个喜欢动手实践的我来说…

力扣206 - 反转链表【校招面试高频考题】

乾坤大挪移~一、题目描述二、思路分析1、头插2、三指针迭代三、整体代码展示【需要自取】1、头插2、三指针迭代四、总结与提炼一、题目描述 原题传送门 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xf…

【Redis】CentOs 虚拟机安装 Redis 缓存数据库

一、使用案例&#xff1a; 以淘宝为例&#xff0c;几个人一起登入淘宝&#xff0c;去检索男装&#xff0c;这几个人的访问都得到相同的结果。这时&#xff0c;我们就可以考虑将男装缓存在一个地方&#xff0c;而不是再去访问数据库&#xff0c;这时&#xff0c;就是我们 Redis…

ctfshow文件包含

web78 源码&#xff1a; if(isset($_GET[file])){$file $_GET[file];include($file); }else{highlight_file(__FILE__);//高亮显示当前文件内容 }解法一 - php://input # http://challenge.ctf.show/?filephp://input # [POST DATA] <?php system(ls)?> <?php…

基于可视图法(VG)的路径规划算法简述

可视图法路径规划&#xff08;VG&#xff09; 可视图法由Lozano-Perez和Wesley于1979年在论文&#xff1a;《An Algorithm for Planning Collision-Free Paths among Polyhedral Obstacles.》中提出。 基于可视图法路径规划算法主要包括以下两个步骤&#xff1a;①可视图的构建…

第二章 环境的选择和安装

1、开发环境操作系统 1.1 选择Windows、Mac or Linux 首先明确一点&#xff1a;我们的首要目的是要快速上手使用Elasticsearch&#xff08;以下简称ES&#xff09;&#xff0c;安装和部署ES并非重点&#xff0c;企业中真正需要你去安装的可能性或者机会非常小。大家可以想一想…

C++运算符重载

运算符重载运算符重载一、重载‘’运算符1.非成员函数版本重载2.成员函数版本二、重载关系运算符三、重载左移运算符四、重载下标运算符五、重载赋值运算符六、重载new和delete1.重载2.内存池七、重载括号运算符八、重载一元运算符运算符重载 C将运算符重载扩展到自定义的数据…

23 张图细讲使用 Devtron 简化 K8S 中应用开发

23 张图细讲使用 Devtron 简化 K8S 中应用开发 在本文中&#xff0c;您将学习如何在多集群环境中使用 Devtron 在 K8S 上进行应用开发。 https://devtron.ai/ Devtron 附带用于构建、部署和管理微服务的工具。它通过提供直观的 UI 和 Helm 图表支持来简化 K8S 上的部署。今天&a…

Java数据结构 | 模拟实现优先级队列

目录 一、前言 二、堆模拟实现优先级队列 2.1 堆的概念 2.2 堆的性质 2.3 堆的存储方式 2.4 堆的创建 一、前言 在前面我们学习过队列&#xff0c;队列是一种先进先出(FIFO)的数据结构&#xff0c;但有些情况下&#xff0c;操作的数据可能带有优先级&#xff0c;一般出队…

mybatis-plus代码生成工具

mybatis-plus版本升级尝试遇到的问题 若遇到高版本&#xff1a;【全局覆盖已有文件的配置已失效&#xff0c;已迁移到策略配置中】or【覆盖已有文件&#xff08;已迁移到策略配置中&#xff0c;3.5.4版本会删除此方法&#xff09;】这句话&#xff0c;可参考文章中解决办法 参考…

python机器人编程——基于单目视觉、固定场景下的自动泊车(下)

目录一、前言二、主要思路step0 设定一个中间位置step1 掉转马头step2 直线匀速前进step3 调整姿态step4 视觉匹配三、效果四、全篇总结一、前言 本篇来讨论一下在固定场景下&#xff0c;如何仅通过单目视觉&#xff0c;实现差速小车的自动停靠&#xff0c;这种方式实现成本比…

_cpp 位图

文章目录1. 位图概念1.1 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中。2. 位图的实现2.1 运行结果&#xff1a;3. 位图应用3.1 具体代码封装实现如下3.2 部分结果演示&#xff1a;3.3 应用总结&#x…

力扣(LeetCode)791. 自定义字符串排序(C++)

排序 这道题只关心 orderorderorder 出现的字符&#xff0c;在 sss 中的排序。 sss 中不在 orderorderorder 的字符&#xff0c;在排序后是什么位置&#xff0c;不影响答案。 可以用 sortsortsort 函数&#xff0c;传入我们自定义的排序方式&#xff0c;按照 orderorderorder …

【JavaSE】类和对象 (二) —— 封装、包以及 static 关键字

目录 1. 封装 1.1 封装的概念 1.2 访问限定符 2. 包 2.1 包的概念 2.2 导入包中的类 2.3 自定义包 2.3.1 包的基本规则 2.3.2 创建一个包 2.4 包访问权限——defualt 3. 何为封装 3.1 private 关键字 4. static 成员 4.1 对学生类的进一步思考 4.2 static 修饰成员变量 4.3 …