【数据结构与算法】二叉树(Binary Tree)

相关推荐:堆(Heap) / 堆排序(HeapSort) / TopK

文章目录

  • 1.树
    • 1.1 树相关概念
    • 1.2 举例树的应用
  • 2. 二叉树
    • 2.1 二叉树分类
    • 2.2 特殊的二叉树
    • 2.3 二叉树的存储结构
  • 3. 二叉树实现与热门问题

1.树

树是一种非线性的数据结构,它看起来像一棵倒挂的树,根朝上而叶子朝下。下图是一棵二叉树,每个节点最多只有两个孩子节点。
在这里插入图片描述

1.1 树相关概念

在这里插入图片描述

  1. 根节点:如上图A节点就是根节点。
  2. 节点的度:一个节点含有的子树的个数,如上图A节点的度为6,F节点的度为3。
  3. 叶节点:度为0的节点,如上图B、C、H、I…等节点为叶节点。
  4. 父节点:也叫双亲节点,如上图E是I和J的父节点,其它节点同理。
  5. 子节点:也叫孩子节点,如上图B、C、D、E等是A的孩子节点。
  6. 兄弟节点:具有相同父节点的节点,如上图P、Q是兄弟节点。
  7. 树的度:最大的节点的度称为树的度,如上图树的度为6。
  8. 节点的层次:从根开始定义起,根为第1层,根的子节点为第2层,以此类推。
  9. 树的高度或深度:树中节点的最大层次,如上图树的高度为4。
  10. 森林:由m(m>0)棵互不相交的树的集合称为森林。
    在这里插入图片描述

1.2 举例树的应用

Linux的文件系统:
在这里插入图片描述
Windows的文件系统也是多叉树,和Linux文件系统不同的是Windows的文件系统可以是森林(至少分了两个盘)。
在这里插入图片描述

2. 二叉树

2.1 二叉树分类

普通的二叉树是没有意义的,存储数据并不比链表或数组好,真正让二叉树有意义的是二叉搜索树(又称二叉排序树或二叉查找树)、AVL树(平衡二叉树)、B树和红黑树。

二叉搜索树:简单地说就是左孩子节点比父节点小、右孩子节点比父节点大的树,二叉树的好处是遍历很快,从名字也能得出它是干嘛的。
在这里插入图片描述
不过极端的二叉搜索树则会造成很多浪费,不仅树另一边节点存储无效的NULL值,最要命的是遍历的时间复杂度增高。
在这里插入图片描述
平衡二叉树二叉树可以解决二叉搜索树的缺点,是其升级版,另外还有B树、红黑树等,感兴趣的小伙伴自行了解或看我其它相关文章,否则本篇文章会占用大量篇幅。

2.2 特殊的二叉树

  1. 满二叉树:每层的节点都是满的。
  2. 完全二叉树:假设树的高度是h,前h-1层的节点都是满的,最后一层也就是h层的节点不一定满,但一定要是有序。满二叉树也是一种特殊的完全二叉树,另外 (heap)也是完全二叉树,想了解的可以看这篇文章:堆(Heap)。
    在这里插入图片描述

2.3 二叉树的存储结构

二叉树可以使用两种结构存储:顺序结构或链式结构,说白了就是数组或链表。

不过对于二叉树而言基本都是用链表存储,因为用数组存储二叉树会浪费很多空间,而极端的二叉树搜索树更甚。
在这里插入图片描述
只有完全二叉树/完全二叉树/堆才适合用数组存储,其特性就决定了不会浪费数组空间,为什么非完全二叉树用数组存储会浪费内存空间,而完全二叉树不会,具体了解请看 文章:堆(Heap)。

C语言表示二叉树的结构:

typedef int valtype;
typedef struct TreeNode {valtype val;struct TreeNode* left;struct TreeNode* right;
} TreeNode;

3. 二叉树实现与热门问题

由于普通的二叉树插入删除操作都是没有意义的,所以这里不实现这种操作;另外由于二叉树通常使用链式存储,所以很多操作都是通过递归实现

申明:

#pragma once#include <stdio.h>
#include <stdlib.h>typedef int valtype;
typedef struct TreeNode {valtype val;struct TreeNode* left;struct TreeNode* right;
} TreeNode;TreeNode* NewNode(valtype val);// 前、中、后序遍历
void PreOrder(TreeNode* root);
void InOrder(TreeNode* root);
void PostOrder(TreeNode* root);// 树节点个数
size_t TreeSize(TreeNode* root);
// 叶子节点个数
size_t TreeLeafSize(TreeNode* root);
// 树高度/深度
size_t TreeHeight(TreeNode* root);
// 第k层节点个数
size_t TreeKthSize(TreeNode* root, int k);

实现:

#define _CRT_SECURE_NO_WARNINGS 1#include "BinaryTree.h"TreeNode* NewNode(valtype val) {TreeNode* treeNode = (TreeNode*)malloc(sizeof(TreeNode));if (treeNode == NULL) {perror("BuyNode malloc failed.\n");exit(-1);}treeNode->val = val;treeNode->left = NULL;treeNode->right = NULL;return treeNode;
}void PreOrder(TreeNode* root) {if (root != NULL) {printf("%d ", root->val);PreOrder(root->left);PreOrder(root->right);}
}void InOrder(TreeNode* root) {if (root != NULL) {InOrder(root->left);printf("%d ", root->val);InOrder(root->right);}
}void PostOrder(TreeNode* root) {if (root != NULL) {PostOrder(root->left);PostOrder(root->right);printf("%d ", root->val);}
}size_t TreeSize(TreeNode* root) {return root == NULL // 本身 + 左子树 + 右子树节点之和? 0 : 1 + TreeSize(root->left) + TreeSize(root->right);
}size_t TreeLeafSize(TreeNode* root) {if (root == NULL) {return 0;}// 非叶子结点的左子树和右子树的叶子节点之和return root->left == NULL && root->right == NULL? 1 : TreeLeafSize(root->left) + TreeLeafSize(root->right);
}size_t TreeHeight(TreeNode* root) {if (root == NULL) {return 0;}// 选出左子树和右子树中较高的树 + 根节点本身高度return max(TreeHeight(root->left), TreeHeight(root->right)) + 1;//size_t left = TreeHeight(root->left);//size_t right = TreeHeight(root->right);//return (left > right ? left : right) + 1; 
}size_t TreeKthSize(TreeNode* root, int k) {if (root == NULL || k < 1) {return 0;}else if (k == 1) { return 1; // 第k层}else { // k > 1 向下走直到来到第k层return TreeKthSize(root->left, k-1) + TreeKthSize(root->right, k-1);}
}

测试:

#define _CRT_SECURE_NO_WARNINGS 1#include "BinaryTree.h"static void BuildTree(TreeNode* root);int main() {TreeNode root; BuildTree(&root);PreOrder(&root);printf("\n");InOrder(&root);printf("\n");PostOrder(&root);printf("\n");printf("TreeSize = %zd\n", TreeSize(&root));printf("TreeLeafSize = %zd\n", TreeLeafSize(&root));printf("TreeHeight = %zd\n", TreeHeight(&root));printf("TreeKthSize = %zd\n", TreeKthSize(&root, 3));return 0;
}static void BuildTree(TreeNode* root) {TreeNode* node2 = NewNode(2);TreeNode* node3 = NewNode(3);TreeNode* node4 = NewNode(4);TreeNode* node5 = NewNode(5);TreeNode* node6 = NewNode(6);TreeNode* node7 = NewNode(7);root->val = 1;root->left = node2;root->right = node4;node2->left = node3;node2->right = node7;node4->left = node5;node4->right = node6;
}

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

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

相关文章

力扣:42. 接雨水 84.柱状图中最大的矩形(单调栈,双指针)

这两道题解题思路类似&#xff0c;一个是单调递增栈&#xff0c;一个是单调递减栈。本篇博客给出暴力&#xff0c;双指针和单调栈解法。 42. 接雨水 题目&#xff1a; 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后…

AMD64 linux 环境中,如何将main.go打包成不带 .exe 的可执行文件?

在终端中先进入main.go所在的文件夹&#xff0c;然后运行这三条命令即可 $env:GOOS"linux" $env:GOARCH"amd64" go build main.go 最终结果&#xff0c;成功出现不带 .exe 结尾的可执行包&#xff1a;

日本失去的三十年:去杠杆用了14年

去年以来&#xff0c;日股在日本央行转鹰预期、基本面改善和一系列监管新规的催化下高歌猛进&#xff0c;日经指数已经逼近90年代资产泡沫时期的高位。今年迄今累计上涨8.51%&#xff0c;领跑全球&#xff0c;“失落的三十年”似乎已经远去。 日本因何走向衰退&#xff1f;“失…

【C语言】位与移位操作符详解

目录 1.⼆进制和进制转换 ①十进制&#xff1a;生活中最常用 ②二进制&#xff1a;计算机中使用的&#xff0c;每个数字称为一个比特 ③八进制、十六进制也如上 ④二进制转十进制 ⑤十进制转二进制 ⑥二进制转八进制 ⑦二进制转十六进制 2.原码、反码、补码 3.移位操…

【已更新】2024美赛C题代码教学思路数据处理数学建模分析Momentum in Tennis

问题一完整的代码已给出&#xff0c;预计2号晚上或者3号凌晨全部给出。 代码逻辑如下&#xff1a; C题第一问要求我们开发一个模型&#xff0c;捕捉得分时的比赛流程&#xff0c;并将其应用于一场或多场比赛。你的模型应该确定哪名球员在比赛的特定时间表现得更好&#xff0c;…

AI-数学-高中-24-三角函数一般形式的各参数含义

原作者视频&#xff1a;三角函数】12三角函数一般形式的各参数含义&#xff08;易&#xff09;_哔哩哔哩_bilibili 1.函数中的A标识符&#xff1a;表示曲线中间平衡位置的振幅&#xff0c;值域为正负A&#xff1a;[-A,A]。 2.函数中的B标识符&#xff1a;决定曲线纵向上下平移…

基于 SpringBoot 和 Vue.js 的权限管理系统部署教程

大家后&#xff0c;我是 jonssonyan 在上一篇文章我介绍了我的新项目——基于 SpringBoot 和 Vue.js 的权限管理系统&#xff0c;本文主要介绍该系统的部署 部署教程 这里使用 Docker 进行部署&#xff0c;Docker 基于容器技术&#xff0c;它可以占用更少的资源&#xff0c;…

linux文件的IO函数

open函数: 作用&#xff1a;打开或者新建一个文件 原型&#xff1a; int open(const char*pathname,int flags); int open(const char*pathname,int flags,mode_t mode); 参数&#xff1a; pathname:路径 flags:1-> O_RONLY 只读打开 2 -> O_WONLY只写打开 3->…

83 CTF夺旗-Python考点SSTI反序列化字符串

这里写目录标题 CTF各大题型简介演示案例:CTF夺旗-Python-支付逻辑&JWT&反序列化CTF夺旗-Python-Flask&jinja2&SSTl模版注入CTF夺旗-Python-格式化字符串漏洞&读取对象 涉及资源&#xff1a; 我们这篇文章主要讲的是CTF在web渗透测试方向的3个考点 CTF各大…

elementui常用组件-个人版(间断更新)

Dialog 对话框 el-dialog <el-dialogtitle"提示":visible.sync"dialogVisible"width"30%":before-close"handleClose"><span>这是一段信息</span><span slot"footer" class"dialog-footer"…

微信小程序(三十六)事件传参

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.传参步骤 2.传参接收解构步骤 源码&#xff1a; index.wxml <button type"primary" bind:tap"onclick" mark:index"{{0}}" mark:remb"{{1}}" class"But&quo…

产品经理--分享在项目中产品与研发之间会遇到的问题 在面试这一岗位时,面试官常问的问题之一,且分享两大原则来回答面试官这一问题

目录 一.STAR原则 1.1 简介 1.2 如何使用 1.3 举例说明 二.PDCA原则 2.1 简介 2.2 如何使用 2.3 运用场景 2.4 举例说明 三.产品与研发的沟通痛点 3.1 沟通痛点的原因 3.2 分享案例 前言 本篇会详细阐明作为一个产品经理会在项目遇到的问题&#xff0c;如&#xff1a;产…

张艺谋《主角》选角引发热议,周迅、赵丽颖、杨紫或成候选。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 近日&#xff0c;张艺谋执导的首部电视剧《主角》女主选角成为…

6.electron之上下文隔离,预加载JS脚本

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

【Linux】vim的基本操作与配置(上)

Hello everybody!今天我们要进入vim的讲解了。学会了vim,咱们就可以在Linux系统上做一些简单的编程啦&#xff01; 那么废话不多说&#xff0c;咱们直接进入正题&#xff01; 1.初识vim vim是一款多模式的文本编辑器&#xff0c;可以对一个文件进行编辑操作。 它一共有三个模…

2024年【化工自动化控制仪表】最新解析及化工自动化控制仪表考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【化工自动化控制仪表】最新解析及化工自动化控制仪表考试资料&#xff0c;包含化工自动化控制仪表最新解析答案和解析及化工自动化控制仪表考试资料练习。安全生产模拟考试一点通结合国家化工自动化控制仪表考…

《dx12 龙书》第四部分学习笔记——预备知识(下)

7、多重采样技术的原理 由于屏幕中显示的像素不可能是无穷小的&#xff0c;所以并不是任意一条直线都能在显示器上“平滑”而完美地呈现出来。即为以像素矩阵 &#xff08;matrix of pixels&#xff0c; 可以理解为“像素2D数组”&#xff09;逼近直线的方法所产生的“阶梯” &…

EDM营销平台哪个好?推荐的邮件营销平台?

EDM邮件营销平台有哪些&#xff1f;外贸EDM邮件营销平台有哪些&#xff1f; EDM营销平台已成为企业推广产品和服务的重要工具。但是&#xff0c;面对市场上众多的EDM营销平台&#xff0c;究竟哪个更好呢&#xff1f;下面&#xff0c;蜂邮EDM将从平台功能、用户体验、数据分析和…

Matlab使用点云工具箱进行点云配准

一、代码 source_pc pcread(bun_zipper.ply); target_pc pcread(bun_zipper2.ply); % 下采样 gridStep 0.001; ptCloudA pcdownsample(source_pc,gridAverage,gridStep); ptCloudB pcdownsample(target_pc,gridAverage,gridStep); % 初始变换矩阵 tform_initial affine3…

C语言笔试题之实现C库函数 pow()(递归的思想)

实例要求&#xff1a; 1、请你实现C库函数 pow()&#xff08;stdio.h & math.h&#xff09; &#xff0c;即计算 x 的整数 n 次幂函数&#xff08;即x^n &#xff09;&#xff1b;2、函数声明&#xff1a;double myPow(double x, int n)&#xff1b;参数&#xff1a;1、x …