【数据结构】树与二叉树(廿五):树搜索指定数据域的结点(算法FindTarget)
文章目录
- 5.3.1 树的存储结构
- 5. 左儿子右兄弟链接结构
- 5.3.2 获取结点的算法
- 1. 获取大儿子、大兄弟结点
- 2. 搜索给定结点的父亲
- 3. 搜索指定数据域的结点
- a. 算法FindTarget
- b. 算法解析
- c. 代码实现
- a. 使用指向指针的指针
- b. 直接返回找到的节点
- 4. 代码整合
5.3.1 树的存储结构
5. 左儿子右兄弟链接结构
【数据结构】树与二叉树(十九):树的存储结构——左儿子右兄弟链接结构(树、森林与二叉树的转化)
左儿子右兄弟链接结构通过使用每个节点的三个域(FirstChild、Data、NextBrother)来构建一棵树,同时使得树具有二叉树的性质。具体来说,每个节点包含以下信息:
- FirstChild: 存放指向该节点的大儿子(最左边的子节点)的指针。这个指针使得我们可以迅速找到一个节点的第一个子节点。
- Data: 存放节点的数据。
- NextBrother: 存放指向该节点的大兄弟(同一层中右边的兄弟节点)的指针。这个指针使得我们可以在同一层中迅速找到节点的下一个兄弟节点。
通过这样的结构,整棵树可以用左儿子右兄弟链接结构表示成一棵二叉树。这种表示方式有时候被用于一些特殊的树结构,例如二叉树、二叉树的森林等。这种结构的优点之一是它更紧凑地表示树,而不需要额外的指针来表示兄弟关系。
A/|\B C D/ \E F
A
|
B -- C -- D|E -- F
即:
A/ B \C/ \ E D\F
5.3.2 获取结点的算法
1. 获取大儿子、大兄弟结点
【数据结构】树与二叉树(二十):树获取大儿子、大兄弟结点的算法(GFC、GNB)
2. 搜索给定结点的父亲
【数据结构】树与二叉树(廿四):树搜索给定结点的父亲(算法FindFather)
3. 搜索指定数据域的结点
a. 算法FindTarget
b. 算法解析
算法FindTarget在以t为根指针的树中搜索数据成员等于target的节点,类似先根遍历,其时间复杂度为O(n) 。
- 首先,将
result
指针设置为空。 - 如果
t
为空,直接返回。 - 如果
t
的数据成员等于target
,表示找到了目标节点,将result
指针指向t
,然后返回。 - 将指针
p
指向t
的第一个子节点。 - 进入一个循环,只要
p
不为空:- 递归调用
FindTarget
函数,传入参数p
和target
,并将结果存储在result
中。 - 如果
result
不为空,表示已经找到了目标节点,直接返回。 - 将指针
p
更新为p
的下一个兄弟节点。
- 递归调用
- 如果循环结束仍然没有找到目标节点,那么
result
仍然为空。
c. 代码实现
a. 使用指向指针的指针
TreeNode* FindTarget(TreeNode* t, char target) {if (t == NULL) {return NULL;}if (t->data == target) {return t;}TreeNode* p = t->firstChild;while (p != NULL) {struct TreeNode* resultt = FindTarget(p, target);if (resultt != NULL) {return resultt;}p = p->nextBrother;}
}
b. 直接返回找到的节点
void FindTarget(TreeNode* t, char target, TreeNode** result) {*result = NULL;if (t == NULL) {return;}if (t->data == target) {*result = t;return;}TreeNode* p = t->firstChild;while (p != NULL) {FindTarget(p, target, result);if (*result != NULL) {return;}p = p->nextBrother;}
}
两种实现方式在逻辑上是等价的,主要的区别在于结果的返回方式和对指针的处理。
4. 代码整合
#include <stdio.h>
#include <stdlib.h>// 定义树节点
typedef struct TreeNode {char data;struct TreeNode* firstChild;struct TreeNode* nextBrother;
} TreeNode;// 创建树节点
TreeNode* createNode(char data) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));if (newNode != NULL) {newNode->data = data;newNode->firstChild = NULL;newNode->nextBrother = NULL;}return newNode;
}// 释放树节点及其子树
void freeTree(TreeNode* root) {if (root != NULL) {freeTree(root->firstChild);freeTree(root->nextBrother);free(root);}
}// 算法GFC:获取大儿子结点
TreeNode* getFirstChild(TreeNode* p) {if (p != NULL && p->firstChild != NULL) {return p->firstChild;}return NULL;
}// 算法GNB:获取下一个兄弟结点
TreeNode* getNextBrother(TreeNode* p) {if (p != NULL && p->nextBrother != NULL) {return p->nextBrother;}return NULL;
}// 队列结构
typedef struct QueueNode {TreeNode* treeNode;struct QueueNode* next;
} QueueNode;typedef struct {QueueNode* front;QueueNode* rear;
} Queue;// 初始化队列
void initQueue(Queue* q) {q->front = NULL;q->rear = NULL;
}// 入队列
void enqueue(Queue* q, TreeNode* treeNode) {QueueNode* newNode = (QueueNode*)malloc(sizeof(QueueNode));newNode->treeNode = treeNode;newNode->next = NULL;if (q->rear == NULL) {q->front = newNode;q->rear = newNode;} else {q->rear->next = newNode;q->rear = newNode;}
}// 出队列
TreeNode* dequeue(Queue* q) {if (q->front == NULL) {return NULL; // 队列为空}TreeNode* treeNode = q->front->treeNode;QueueNode* temp = q->front;q->front = q->front->next;free(temp);if (q->front == NULL) {q->rear = NULL; // 队列为空}return treeNode;
}// 层次遍历的算法
void LevelOrder(TreeNode* root) {if (root == NULL) {return;}Queue queue;initQueue(&queue);enqueue(&queue, root);while (queue.front != NULL) {TreeNode* p = dequeue(&queue);while (p != NULL) {// 访问当前结点printf("%c ", p->data);// 将大儿子结点入队列if (getFirstChild(p) != NULL) {enqueue(&queue, getFirstChild(p));}// 移动到下一个兄弟结点p = getNextBrother(p);}}
}// 算法 FindTarget
void FindTarget(TreeNode* t, char target, TreeNode** result) {*result = NULL;if (t == NULL) {return;}if (t->data == target) {*result = t;return;}TreeNode* p = t->firstChild;while (p != NULL) {FindTarget(p, target, result);if (*result != NULL) {return;}p = p->nextBrother;}
}// TreeNode* FindTarget(TreeNode* t, char target) {
// if (t == NULL) {
// return NULL;
// }
//
// if (t->data == target) {
// return t;
// }
//
// TreeNode* p = t->firstChild;
//
// while (p != NULL) {
// struct TreeNode* resultt = FindTarget(p, target);
//
// if (resultt != NULL) {
// return resultt;
// }
//
// p = p->nextBrother;
// }
// }int main() {// 构建左儿子右兄弟链接结构的树TreeNode* A = createNode('A');TreeNode* B = createNode('B');TreeNode* C = createNode('C');TreeNode* D = createNode('D');TreeNode* E = createNode('E');TreeNode* F = createNode('F');A->firstChild = B;B->nextBrother = C;C->nextBrother = D;C->firstChild = E;E->nextBrother = F;// 要查找的目标值char targetValue = 'C';// 使用算法 FindTarget 查找结点// TreeNode* result = FindTarget(A, targetValue);TreeNode* result = NULL;FindTarget(A, targetValue, &result);// 输出结果if (result != NULL) {printf("Node with data %c found.\n", targetValue);} else {printf("Node with data %c not found.\n", targetValue);}// 层次遍历printf("Level Order: \n");LevelOrder(result);printf("\n");// 释放树节点freeTree(A);return 0;
}
相关文章:

【数据结构】树与二叉树(廿五):树搜索指定数据域的结点(算法FindTarget)
文章目录 5.3.1 树的存储结构5. 左儿子右兄弟链接结构 5.3.2 获取结点的算法1. 获取大儿子、大兄弟结点2. 搜索给定结点的父亲3. 搜索指定数据域的结点a. 算法FindTargetb. 算法解析c. 代码实现a. 使用指向指针的指针b. 直接返回找到的节点 4. 代码整合 5.3.1 树的存储结构 5.…...

深度学习图像风格迁移 - opencv python 计算机竞赛
文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习图像风格迁移 - opencv python 该项目较为新颖,适合作为竞赛课题…...
提高SQL语句执行效率的8个方法
提高SQL语句执行效率的8个方法 在日常的数据库操作中,如何提高SQL语句的执行效率是每个程序员都需要关注的问题,SQL语句的执行效率对系统的性能有着重要影响,本文将介绍8种提高SQL语句执行效率的方法。 合理使用索引 索引介绍 索引是数据…...

C语言,通过数组实现循环队列
实现循环队列最难的地方就在于如何判空和判满,只要解决了这两点循环队列的设计就没有问题。接下来我们将会使用数组来实现循环队列。 接下来,为了模拟实现一个容量为4的循环队列,我们创建一个容量为4 1 的数组。 接下来我们将会对这个数组…...

python+pygame+opencv+gpt实现虚拟数字人直播(一)
AI技术突飞猛进,不断的改变着人们的工作和生活。数字人直播作为新兴形式,必将成为未来趋势,具有巨大的、广阔的、惊人的市场前景。它将不断融合创新技术和跨界合作,提供更具个性化和多样化的互动体验,成为未来的一种趋…...

c语言:模拟实现各种字符串函数(2)
strncpy函数: 功能:拷贝指定长度的字符串a到字符串b中 代码模拟实现: //strncpy char* my_strncpy(char* dest, char* str,size_t num) {char* ret dest;assert(dest && str);//断言,如果其中有一个为空指针ÿ…...

【Proteus仿真】【STM32单片机】感应水龙头设计
文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真STM32单片机控制器,使用LCD1602液晶模块、HCSR04超声波等。 主要功能: 系统运行后,LCD1602显示超声波模块检测的距离,若检测距离小…...

P15 C++ 枚举
The ChenPi 前言 今天我们要讲的是 C 中的枚举。 enum 是 enumeration 的缩写,基本上可以说,它就是一个数值集合。如果你想要给枚举一个更实际的定义,它们是给一个值命名的一种方法。 所以我们不用一堆叫做 A、B、C 的整数。我们可以有一个…...

深入理解路由协议:从概念到实践
路由技术是Internet得以持续运转的关键所在,路由是极其有趣而又复杂的课题,永远的话题。 SO:这是一个解析路由协议的基础文章。 目录 前言路由的概念路由协议的分类数据包在网络中的路由过程理解路由表的结构路由器关键功能解析 前言 在互联…...

Qt 串口编程-从入门到实战
1. Qt 串口通信流程解析 1.1 串行通信和并行通信对比 并行通信适合距离较短的通信,且信号容易受干扰,成本高串口通讯-设备(蓝牙, wifi, gprs, gps) 1.2 Qt 串口通信具体流程 1. 创建 QSerial…...

如何获得微软MVP徽章
要成为微软MVP,需要在特定领域成为专家,并积极参与社区,为其他人提供帮助和支持。以下是一些步骤可以帮助你成为MVP: 在特定领域成为专家:要成为MVP,需要在某个领域具有专业知识和经验。这可以通过阅读相关…...

Java架构师软件架构开发
目录 1 基于架构的软件开发导论2 ABSD架构方法论3 ABSD方法论具体实现4 ABSD金融业案例5 基于特定领域的软件架构开发导论6 DSSA领域分析7 DSSA领域设计和实现8 DSSA国际电商平台架构案例9 架构思维方法论概述10 AT方法论和案例想学习架构师构建流程请跳转:Java架构师系统架构…...

西南科技大学数字电子技术实验一(数字信号基本参数与逻辑门电路功能测试及FPGA 实现 )预习报告
手写报告稍微认真点写,80+随便有 目录 一、计算/设计过程 1、通过虚拟示波器观察和测量信号 2、通过实际电路(电阻、开关、发光二极管)模拟逻辑门电路 二、画出并填写实验指导书上的预表...
Java八股文面试全套真题【含答案】- SpringMVC篇
以下是一些关于Spring MVC语言的经典面试题以及它们的答案: 什么是Spring MVC框架?它的特点是什么? Spring MVC是基于Java的一种Web应用框架,用于开发基于MVC(模型-视图-控制器)模式的Web应用程序。它的特…...

Spring第二课响应的完全,如何理解前后端互联
目录 一、响应 Control,RestController 1.Controller的源码,代表什么意思 2.返回数据 Responsebody 3.返回HTML片段 4.返回JSON 5.那么假如我们使用集合会怎么样呢 设置状态码,虽然不影响展示,但是确实显示起来也就是401的情况。 2.我…...

html实现各种瀑布流(附源码)
文章目录 1.设计来源1.1 动态响应瀑布流1.2 分页瀑布流1.3 响应瀑布流 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/134613121 html实现各种瀑布流(附源码),…...

万字解析设计模式之责任链模式、状态模式
目录 一、责任链模式 1.1概述 1.2结构 1.3实现 1.4 优缺点 1.5应用场景 1.6源码解析 二、状态模式 2.1概述 2.2结构 2.3实现 2.4优缺点 2.5应用场景 三、责任链模式实验 任务描述 实现方式 编程要求 测试说明 四、状态模式实验 任务描述 实现方式 编程要…...
二十三种设计模式全面解析-深入探讨状态模式的高级应用技术:释放对象行为的无限可能
在软件开发中,状态管理是一个常见的挑战。当对象的行为随着内部状态的变化而变化时,有效地管理对象的状态和相应的行为变得至关重要。在这方面,状态模式提供了一种优雅而灵活的解决方案。它允许对象在运行时根据内部状态的改变而改变其行为&a…...

论文笔记--Toolformer: Language Models Can Teach Themselves to Use Tools
论文笔记--Toolformer: Language Models Can Teach Themselves to Use Tools 1. 文章简介2. 文章概括3 文章重点技术3.1 Toolformer3.2 APIs 4. 文章亮点5. 原文传送门 1. 文章简介 标题:Toolformer: Language Models Can Teach Themselves to Use Tools作者&#…...

stm32实现0.96oled图片显示,菜单功能
stm32实现0.96oled图片显示,菜单功能 功能展示简介代码介绍oled.coled.holedfont.h(字库文件)main函数 代码思路讲解 本期内容,我们将学习0.96寸oled的进阶使用,展示图片,实现菜单切换等功能,关…...

微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心
当仓库学会“思考”,物流的终极形态正在诞生 想象这样的场景: 凌晨3点,某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径;AI视觉系统在0.1秒内扫描包裹信息;数字孪生平台正模拟次日峰值流量压力…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

实战设计模式之模板方法模式
概述 模板方法模式定义了一个操作中的算法骨架,并将某些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的前提下,重新定义算法中的某些步骤。简单来说,就是在一个方法中定义了要执行的步骤顺序或算法框架,但允许子类…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...

python可视化:俄乌战争时间线关键节点与深层原因
俄乌战争时间线可视化分析:关键节点与深层原因 俄乌战争是21世纪欧洲最具影响力的地缘政治冲突之一,自2022年2月爆发以来已持续超过3年。 本文将通过Python可视化工具,系统分析这场战争的时间线、关键节点及其背后的深层原因,全面…...