再谈二叉树

Zephyr OS实战指南:从入门到精通物联网开发 本文提供了一份详尽的Zephyr OS实战指南,涵盖从开发环境搭建到物联网应用开发的全过程。文章详细介绍了如何利用Zephyr OS进行线程管理、设备驱动开发、低功耗设计以及蓝牙通信,并通过具体代码示例帮助开发者快速掌握这一专为物联网设备设计的开源实时操作系统,实现从入门到精通的跨越。 阅读详情
由于树结构经常是面试官拷问的知识点,掌握好它是必须的,又看了些资料,再试着记录一点心得。

一般无规律的树没什么意义,太复杂面试时间也有限。所以主要讨论的是二元搜索树(binary search tree)

二元搜索树的优势是查找很快。时间复杂度是O(log2(n)),也常写成O(log(n)).
因为比如

    70
   /  /
  50   90
 / /   / /
40 45 80 120
 
查询40这个节点,需要3次遍历,整个树节点是7。  于是有这个关系
       2x = n (x代表次数, n代表节点树(data size))

       x = log2n 

这种指数级的速度是很快的。2的10次方等于1204, 在这里等效为最多10次就可以从1024个数据中找出需要的节点来。

不过如果二叉树左右分布不均的话,甚至每个节点只有一个右节点,这样就成了链结构,就失去了该优势。

代码:

结构定义:
  1. typedef struct nodeT
  2. {
  3.     struct nodeT *left;
  4.     struct nodeT *right;
  5.     int value;
  6. }node;

初始化二元搜索树

  1. #include <assert.h>
  2. #define NUM 7
  3. int data[NUM] = {70, 50, 90, 40, 45, 80, 120};
  4. /*
  5. input:
  6. data: 新节点data值
  7. return:
  8. 新节点指针
  9. */
  10. PNode newNode(int data)
  11. {
  12.     PNode p = (PNode)malloc(sizeof(Node));
  13.     assert( p != NULL);
  14.     p->data = data;
  15.     p->lChild = NULL;
  16.     p->rChild = NULL;
  17.     return p;
  18. }
  19. /* 
  20. return:
  21.   false:插入重复data值节点
  22.   true: 成功构建
  23. */
  24. bool CreateBTree(PNode &root)
  25. {
  26.     int i;
  27.     root = newNode(data[0]);
  28.     PNode p;
  29.     PNode parent;
  30.     for (i=1; i<NUM; i++)
  31.     {
  32.         p = root;
  33.         while (p != NULL)
  34.         {
  35.             // 保存插入节点的父节点
  36.             parent = p;
  37.             if (data[i] > p->data)
  38.                 p = p->rChild;
  39.             else if (data[i] < p->data)
  40.                 p = p->lChild;
  41.             // 要求节点data值不重复
  42.             else
  43.                 return false;
  44.         }
  45.         if (p == NULL)
  46.         {
  47.             // 新建节点,设置其data值和父节点
  48.             p = newNode(data[i]);
  49.             //p->parent = parent;
  50.             if (p->data < parent->data)
  51.                 parent->lChild = p;
  52.             else
  53.                 parent->rChild = p;
  54.         }
  55.     }
  56.     return true;
  57. }
遍历:

  1. void PreOrderTraversal(PNode root)
  2. {
  3.     if (root == NULL)
  4.         return;
  5.     else
  6.     {
  7.         // printf的位置决定了三种遍历方法
  8.         printf("%d ", root->data);
  9.         PreOrderTraversal(root->lChild);
  10.         PreOrderTraversal(root->rChild);
  11.     }
  12. }

查询节点:
  1. /*
  2. params:
  3.   value: 寻找data值为value的节点
  4. return:
  5.   成功: 返回该节点
  6.   失败: 返回NULL
  7. */
  8. PNode SearchNode(PNode root, int value)
  9. {
  10.     if (root == NULL)
  11.         return NULL;
  12.     
  13.     PNode p = root;
  14.     while (p)
  15.     {
  16.         if (p->data < value)
  17.             p = p->rChild;
  18.         else if (p->data > value)
  19.             p = p->lChild;
  20.         else
  21.             return p;
  22.     }   
  23.     return NULL;
  24. }
增加父节点
  1. PNode newNode(int data)
  2. {
  3.     PNode p = (PNode)malloc(sizeof(Node));
  4.     assert( p != NULL);
  5.     p->data = data;
  6.     p->lChild = NULL;
  7.     p->rChild = NULL;
  8.     p->parent = NULL;   //添加
  9.     return p;
  10. }
  11. /*
  12. 添加父节点
  13. */
  14. void AddParent(PNode root)
  15. {
  16.     PNode p;
  17.     if (root == NULL)
  18.         return;
  19.     p = root;
  20.     if (root->lChild != NULL)
  21.     {
  22.         root->lChild->parent = p;
  23.         AddParent(root->lChild);
  24.     }
  25.     if (root->rChild != NULL)
  26.     {
  27.         root->rChild->parent = p;
  28.         AddParent(root->rChild);
  29.     }
  30. }



           
单片机技术入门与实战:从零基础到项目开发 单片机(MCU)作为嵌入式系统的核心组件,集成了CPU、内存和各种接口电路,广泛应用于智能家居、工业控制和汽车电子等领域。其工作原理基于实时控制和低功耗设计,通过定时器、中断系统和通信接口等功能模块实现各种控制任务。在物联网和智能硬件快速发展的背景下,掌握单片机开发技术成为电子工程师的重要技能。本文以STM32和PIC系列为例,详细解析单片机的基本概念、功能模块和选型指南,并分享从入门到项目实战的系统学习方法,帮助开发者在3-6个月内快速掌握这一关键技术。 阅读详情

相关推荐

FPGA远程升级必备:STARTUPE2原语控制Flash的避坑指南

本文深入解析了FPGA远程升级中STARTUPE2原语的核心价值与配置策略,详细介绍了其在QSPI Flash接口设计中的应用。通过Vivado工具和原语控制,开发者可以高效实现安全可靠的远程固件升级,提升系统稳定性和升级效率。

k8l9m0n的博客 395

再谈二叉树的遍历

再谈二叉树的遍历前言一、解法一:递归解法二、解法二:迭代法2.1 先序和中序2.2 后序三、解法三 前言 以前在学习数据结构的时候曾经写过一些关于二叉树遍历的博客。最近在刷题的时候,对二叉树的遍历又有了一些新的解法和思路,这里做一总结,希望可以便人便己。 一、解法一:递归解法 关于二叉树的遍历,最简单而又最直接的方式就是利用其本身的特点—即二叉树的左右子树同样是一棵二叉树。这是一个递归定义,所以非常适合采用递归的解法。思路很简单,这里就不赘述了,直接上代码。 void PreOrderDfs(TreeNo

xiaopan的博客 284

基于决策树的英雄联盟比赛胜负预测(含完整代码)

在代码中设置随机种子(例如 RANDOM_SEED = 2024)的主要目的是为了确保每次运行代码时,随机过程的结果是一致的。通过绘制不同参数组合下的准确率图,直观地展示了参数对模型性能的影响,帮助读者更好地理解和选择合适的参数。通过设置相同的随机种子(伪随机数),可以确保每次运行代码时,随机数生成器生成的随机数序列是相同的。如果在开发过程中遇到问题,设置固定的随机种子可以帮助你更容易地定位问题,因为每次运行代码时的数据和结果都是一样的。在科学研究和实验中,结果的可重复性是非常重要的。

oisflo的博客 1919

再谈二叉树(上)

二叉树是重要的数据结构内容,我们今天再来讲一下二叉树相关知识点。 定义与结构 首先再次明确一下什么是二叉树: 二叉树(binary tree)是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。 一颗正常的二叉树。 我们怎么在计算机中储存二叉树呢没也就是说它的结构是什么样的呢,这就要用到我们的链表了。 类似于指针,也需要用到结构.

qq_62272360的博客 217

revit二次开发环境搭建(2024版)(小白友好)

revit二次开发环境配置,SDK、addin manager和lookup新手友好安装教程

m0_56961251的博客 1419

揭秘 Chat Template 如何驱动 AI Agent?以Qwen3为例详解LLM的聊天模板

bos_token: null (没有使用特殊的文档开始符)eos_token<|im_end|>(作为每个对话回合的结束符)pad_token: 对话回合开始<|im_end|>: 对话回合结束非特殊但关键的控制 Token (在词汇表中定义): 包裹模型生成的工具调用请求。: 包裹外部工具返回的执行结果。<think></think>: 包裹模型的内部思考或推理过程。

ljp1919的专栏 1352

再谈二叉树(下)

上一期我们已经介绍了而二叉树的基础了,那么我们下面看一下更多的相关问题。 根据遍历构造二叉树 是不是每一种遍历组合都能构造出二叉树呢?答案是否。前序遍历和后序遍历的组合是不能确定为一二叉树的。前序和后序在本质上都是将父节点与子结点进行分离,但并没有指明左子树和右子树的能力,因此得到这两个序列只能明确父子关系,而不能确定一个二叉树。 先看一个题: 根据先序遍历的特点可知,第一个字符一定是代表最顶端的父节点,之后我们要确定做分支和右分支的界限,就是如何区分左右节点。这时就要借助中序遍历,我们知道中序

qq_62272360的博客 1034

用 Docker 一键部署 SillyTavern酒馆 mac/windows/linux通用教程,我再也不手动折腾了!

本文介绍了如何使用 Docker 一键部署 SillyTavern 项目,适用于 Mac、Windows 和 Linux 系统。SillyTavern 是一个本地部署的大语言模型聊天界面,支持多种插件和扩展。文章详细说明了安装 Docker、拉取项目、启动容器、配置白名单、启用插件等步骤,并提供了常见问题的解决方法。通过 Docker 部署,用户可以避免繁琐的手动配置,快速搭建和运行 SillyTavern,适合希望简化部署流程的用户。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2620

再谈二叉树:重建二叉树

题目是这样的:给出二叉树的前序遍历和后序遍历结果,存储在整型数组中。据此构建出该二叉树。 思路分析:主要考虑到遍历的特点,可以[参考之前的一篇博客]。(http://blog.youkuaiyun.com/xjtuse2014/article/details/51394002)我们可以根据前序遍历结果找到根节点,也就是前序遍历结果的第一个元素,然后在中序遍历结果中找到根节点,那么根节点的左边的元素就是左子树,

xjtuse2014的博客 364

YOLOv11改进 | 特殊场景检测篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)

本文给大家带来的改进机制是低照度图像增强网络SCINet,SCINet(自校正照明网络)是一种专为低光照图像增强设计的框架。它通过级联照明学习过程和权重共享机制来处理图像,优化了照明部分以提升图像质量。我将该网络集成在YOLOv11的主干上针对于图像的输入进行增强,同时该网络的并不会增加参数和计算量,基本和普通的网络结构保持一致,同时该结构支持自定义调节层数,来控制图像增强的效果 ,非常适合想要在黑夜目标检测领域发表文章的读者,该基本网络不会影响模型的速度。欢迎大家订阅我的专栏一起学习YOLO!

Snu77的博客 2206

Java小白入门200例81之Java接口

作者简介 作者名:编程界明世隐 简介:优快云博客专家,从事软件开发多年,精通Java、JavaScript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞! 引言 很多Java初学者问我,新手明明很用心、很努力学习的Java知识,转头又忘记了,很让人犯愁,小白如何能够快速成长、成为大牛呢? 其实要成为大神的技巧只有一个:“多学多练”,于是明哥就整理了比较典型的练习实例,通过练习能够快速提升编码技巧和熟练度,让你在成为大

编程界明世隐的博客 1358

再谈二叉树(二叉树概念,二叉树的性质,二叉树的存储结构)

树的概念 树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:每个结点有零个或多 个子结点;没有父结点的结点称为根结点;每一个非根结点有且只有一个父结点;除了根结点外,每个子结 点可以分为多个不相交的子树 一些基本概念 节点的度:一个节点含有的子树的个数称...

LXY的博客 389

万字详解YOLOv8网络结构Backbone/neck/head以及Conv、Bottleneck、C2f、SPPF、Detect等模块

YOLOv8是由Ultralytics开发的最先进的目标检测模型,推升了速度、准确性和用户友好性的界限。YOLO这一缩写代表“你只看一次”(You Only Look Once),通过在一次网络传递中同时预测所有边界框,提升了算法的效率和实时处理能力。相比之下,其他一些目标检测技术需要经过多个阶段或过程来完成检测。YOLOv8在流行的YOLOv5架构上进行了扩展,在多个方面提供了改进。

专注于图像领域,主要研究内容包括计算机视觉和深度学习,特别是在图像分类、目标检测和图像生成等方面有深入的研究和实践经验。 14万+

谈PHP的二叉树的表示

PHP已经发行到了5.2.10了,5.3.0rc4也已公布。6.0早就出了测试版。PHP是日趋完美。呵呵但是在C++/C中有个重要的概念就是链表。而链表中有个重要概念就是二叉树。实现二叉树关键是一个节点如何表示。我们知道C++/C中可以使用以下代码表示一个二叉树的节点(使用模板):template struct nodeType{    elemType info;  

luojxun的专栏 3748

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

BinaryTree(二叉树) - 再谈二叉树

  经过两天的研究,总算是完全梳理清二叉树的基本操作了,然后我又发现了一些对二叉树的新的认识。   先具体说说删除操作,前面在对二叉树的补充中,我说到了二叉树的删除操作可以有两种不同的代码编写方式(可点这里去看一下),这点我还是这么认为,但在此基础上我又发现我对书上的理解还不够的地方:   用图来说明(删除图中节点65):   按我的上一篇关于二叉树的删除操作的第二种说法对这种...

ding7530的博客 201

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

由二叉树的遍历谈递归

最近复习一下数据结构,又加深了一些问题的理解。 递归大家都很熟悉了,但是什么时候能用递归?什么时候不能用递归呢?大家在学习汉诺塔、二叉树和树的时候经常用到递归,但是为什么这些时候能用递归,而其他时候不能用到递归呢? 递归的使用就是知道递归的次数是可知的并且是恒定的(这里的次数并不是递归的深度,举个例子吧,遍历二叉树的根节点后,你明确的知道要遍历左子树和右子树,那么这里的次数就是2,2是...

weixin_30878361的博客 64

再谈二叉树的层次(宽度)遍历

之前转载过二叉树的层次遍历

hello_qingwen的专栏 650

简要谈一下二叉树和回溯之间区别,以及如何构建一个二叉树

回溯是通过for循环横向遍历,递归纵向遍历进行递归。如果理解二叉树的构建有难度的同学可以先去力扣上做一下层序遍历的模板题目。下面给大家写一下关于二叉树的acm模式的代码(主要是树的构建)下图是求解组合的回溯问题,大家可以自己体会一下两者不同。两者之间大体区别,二叉树是通过左右孩子的地址进行递归。回溯不是真实的树,方便理解。结果:二叉树是真实存在的数据结构,是树。构建二叉树只是再其中加了几行代码而已。用两道简单题目分析不同。上图二叉树的前序遍历。

YNAhaha的博客 164

初夏小谈:二叉树的三种遍历(1)

二叉树的遍历一般分为三种即为,前序遍历,中序遍历,后序遍历。 所谓前序遍历就是从二叉树的根节点出发,先访问根节点,在访问左孩子,然后访问右孩子。注意这是对于每一个结点都符合的条件。 中序遍历就是先访问左孩子,再访问根节点,最后访问右孩子。同样对每个节点都适用。 后序遍历则是先访问左孩子,在访问右孩子,最后访问根节点。每个节点都是如此。 知道了三种遍历方式后拿一个图来先看看各自的遍历顺序...

Scissors_初夏的博客 433

再谈二叉树:三种遍历六种实现

二叉树的遍历:前序、中序’后序,其实,是以根节点的访问顺序来确定的,具体看下面://记法:根节点的遍历顺序就是树的遍历顺序 /************************************************************************/ // V --访问根节点 // L --遍历左子树 // R -- 遍历右子树 // V

xjtuse2014的博客 520

谈遍历二叉树的方法(实例列举二叉链表实现二叉树)

二叉树的遍历有很多的方法,有递归前序遍历、递归中序遍历、递归后续遍历、非递归前序遍历、非递归中序遍历、非递归后续遍历以及非递归层次遍历、递归层次遍历,这些方法有需要栈辅助的,有需要队列辅助的,有需要双队列辅助。 除了二叉树的遍历以外,二叉树的输入也是有多重方法,比如按缩进输出,按普通的方法输出。 下面是近期做的一个关于二叉树遍历的程序。这个程序用到了递归(前序遍...

weixin_34291004的博客 199

再谈数据结构(二)数和二叉树

1 - 引言 关于树和二叉树,我们需要达到的能力有: 熟悉树和二叉树的有关概念 熟悉二叉树的性质 熟练掌握遍历二叉树的递归算法,并灵活运用 知道线索二叉树,会对二叉树进行线索化 递归遍历二叉树及其应用 构造赫夫曼树和赫夫曼编码 树和二叉树的转换 森林和二叉树的转换 遍历树和森林 本文着重在树和二叉树实际应用与代码实现基本操作,对概念就不再赘述 2 - ...

HHH_ANS的博客 617

初夏小谈:LC.107:二叉树的层序遍历

题目描述: 给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历) 例如: 给定二叉树[3,9,20,null,null,15,7], 3 / \ 9 20 / \ 15 7 返回其自底向上的层次遍历为: [ [15,7], [9,20], [3] ] 解题思路: ...

Scissors_初夏的博客 325

初夏小谈:前序构造二叉树及三种遍历(完整版)

通过前序来构造出一棵二叉树,创建一颗二叉树,可以先创建根节点,后再创建它的左孩子和右孩子。遇到空就停止。对于每个结点都是先创建它的左孩子,之后再创建它的右孩子。 但是在创建左孩子和右孩子是,最大的问题就是,待创建数据要移动相应的位。每消耗一个数据就要取下一个元素。可以通过一个变量来计数移动的个数。此外要将每个根节点的左右孩子接起来。因此也要记录每个根节点来连接它的左右孩子。并且进行三种遍历。 ...

Scissors_初夏的博客 645

初夏小谈:LC.236:找寻二叉树中两个结点的公共祖先

题目描述: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。” 例如,给定如下二叉树: root =[3,5,1,6,2,0,8,null,null,7,4] 示例 1: 输入: roo...

Scissors_初夏的博客 555

再谈经典面试题:Leetcode 236 二叉树的最近公共祖宗

这里假设p和q一定存在 二叉树的最近公共祖先的定义是: 从这个节点出发,左子数一定是第一个包含p或者q,右子数一定是第一个包含p和q,这种情况下这个节点可以被称位是最近公共祖先。或者当前这个节点等于p或者q,然后左子数或者右子数包含p或者q,以上就是全部的情况。因此就可以写出递归的代码: class Solution { public: TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) ...

wwxy1995的博客 122

剑指offer:(19)面试官谈面试思路:二叉树的镜像

package co.com.jianzhioffer; public class Solution19 { public class TreeNode { int val; TreeNode left = null; TreeNode right = null; TreeNode(int val) { this.val = val; } } public

skyxmstar的博客 423
上一篇: 数组结构
下一篇: 学习vc6.0编译器
gnuser
博客等级 码龄20年 35粉丝 141原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值