【数据结构】树与二叉树(廿五):树搜索给定结点的父亲(算法FindFather)

本文主要是介绍【数据结构】树与二叉树(廿五):树搜索给定结点的父亲(算法FindFather),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 5.3.1 树的存储结构
    • 5. 左儿子右兄弟链接结构
  • 5.3.2 获取结点的算法
    • 1. 获取大儿子、大兄弟结点
    • 2. 搜索给定结点的父亲
      • a. 算法FindFather
      • b. 算法解析
      • c. 代码实现
    • 3. 代码整合

5.3.1 树的存储结构

5. 左儿子右兄弟链接结构

【数据结构】树与二叉树(十九):树的存储结构——左儿子右兄弟链接结构(树、森林与二叉树的转化)
  左儿子右兄弟链接结构通过使用每个节点的三个域(FirstChild、Data、NextBrother)来构建一棵树,同时使得树具有二叉树的性质。具体来说,每个节点包含以下信息:

  1. FirstChild: 存放指向该节点的大儿子(最左边的子节点)的指针。这个指针使得我们可以迅速找到一个节点的第一个子节点。
  2. Data: 存放节点的数据。
  3. 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. 搜索给定结点的父亲

  • 递归思想
    • 给定结点是指给定的是一个指向某个结点的指针(比如p)。
    • 返回值也应该是指针,指向结点p之父亲的指针(找不到时为空)。

a. 算法FindFather

在这里插入图片描述

b. 算法解析

  算法FindFather在以t为根指针的树中搜索指针p所指节点的父节点,类似先根遍历,其时间复杂度为O(n) 。

  1. 首先,将result指针设置为空。
  2. 如果t为空或者p为空,或者p等于t,那么直接返回。
  3. 将指针q指向t的第一个子节点。
  4. 进入一个循环,只要q不为空:
    • 如果q等于p,表示找到了p的父节点,将result指针指向t,然后返回。
    • 否则,递归调用FindFather函数,传入参数q和p,并将结果存储在result中。
    • 如果result不为空,表示已经找到了父节点,直接返回。
    • 将指针q更新为q的下一个兄弟节点。
  5. 如果循环结束仍然没有找到父节点,那么result仍然为空。

c. 代码实现

void FindFather(TreeNode* t, TreeNode* p, TreeNode** result) {*result = NULL;if (t == NULL || p == NULL || p == t) {return;}TreeNode* q = t->firstChild;while (q != NULL) {if (q == p) {*result = t;return;}FindFather(q, p, result);if (*result != NULL) {return;}q = q->nextBrother;}
}

  递归流程概述:

  • 如果树为空或者给定结点为空或者给定结点是根节点,则根据定义返回NULL
  • q指向根结点的左儿子结点,进入循环
    • 如果给定结点是根结点的左儿子,则根节点就是其父亲
    • 在左儿子子树中递归查找
      • …………
    • 如果找到了父节点,直接返回
    • 没有找到,则q更新为左儿子的右兄弟(即下一个个子结点)
      • 继续循环递归查找…………

3. 代码整合

#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);}
}// 算法 FindFather
void FindFather(TreeNode* t, TreeNode* p, TreeNode** result) {*result = NULL;if (t == NULL || p == NULL || p == t) {return;}TreeNode* q = t->firstChild;while (q != NULL) {if (q == p) {*result = t;return;}FindFather(q, p, result);if (*result != NULL) {return;}q = q->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;// // 层次遍历算法// printf("Level Order: \n");// LevelOrder(A);// printf("\n");// 要查找父亲的节点TreeNode* targetNode = E;TreeNode* result = NULL;// 使用算法 FindFather 查找父亲FindFather(A, targetNode, &result);// 输出结果if (result != NULL) {printf("The father of %c is %c\n", targetNode->data, result->data);} else {printf("Node not found or it is the root.\n");}// 释放树节点freeTree(A);return 0;
}

在这里插入图片描述

这篇关于【数据结构】树与二叉树(廿五):树搜索给定结点的父亲(算法FindFather)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/431757

相关文章

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

C# ComboBox下拉框实现搜索方式

《C#ComboBox下拉框实现搜索方式》文章介绍了如何在加载窗口时实现一个功能,并在ComboBox下拉框中添加键盘事件以实现搜索功能,由于数据不方便公开,作者表示理解并希望得到大家的指教... 目录C# ComboBox下拉框实现搜索步骤一步骤二步骤三总结C# ComboBox下拉框实现搜索步骤一这

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig