算法笔记(有根树遍历)

DFS深度优先搜索之无根树的深度优先遍历(#树的重心) 本篇文章面向初学DFS的萌新(),说说我在做这个题目的碰壁与感悟。 阅读详情
 public class TreeNode
    {
        public string Key { get; set; }
        public object Data { get; set; }
        public TreeNode Parent;
        public List<TreeNode> Children { get; set; }
        public TreeNode(string Key,object Data)
        {
            Children = new List<TreeNode>();
            this.Key = Key;
            this.Data = Data;
        }
        public void AddChild(TreeNode node)
        {
            this.Children.Add(node);
            node.Parent = this;
        }
        public void DelChild(TreeNode node)
        {
            this.Children.Remove(node);
        }
    }
    public class Trees
    {
        public TreeNode Root { get; set; }
        /// <summary>
        /// 非递归遍历树方法,这里采用的先父后子的顺序遍历.如果要先子后父的话,则需要用到两个栈,两个循环.
        /// </summary>
        /// <param name="ListCurrNode"></param>
        public void ListChildren(Action<TreeNode> ListCurrNode)
        {
            if (Root == null)
            {
                return;
            }
            //先父后子
            Stack<TreeNode> _nodesStack1 = new Stack<TreeNode>();
            while (_nodesStack1.Count > 0)
            {
                TreeNode node = _nodesStack1.Pop();
                ListCurrNode(node);
                foreach (var item in node.Children)
                {
                    _nodesStack1.Push(item);
                }
            }
            //先子后父.其实对于二叉树的左序和右序访问,也需要两个栈来实现.
            _nodesStack1.Clear();
            _nodesStack1.Push(Root);
            Stack<TreeNode> _nodesStack2 = new Stack<TreeNode>();
            while (_nodesStack1.Count > 0)
            {
                TreeNode node = _nodesStack1.Pop();
                _nodesStack2.Push(node);
                foreach (var item in node.Children)
                {
                    _nodesStack1.Push(item);
                }
            }
            while (_nodesStack2.Count > 0)
            {
                TreeNode node = _nodesStack1.Pop();
                ListCurrNode(node);
            }
        }

        /// <summary>
        /// 非递归中序,线性时间,常数额外辅助空间方式,不能修改树(临时的也不行),可以遍历任意的叉树.对于K叉树,每次退回的比较时间为<=K,
        /// 因为每个节点至多需退回一次,则退回比较为<=Kn次,树遍历本身的O(n).遍历还是线性时间。
        /// 其实如果可以修改树,比如设置访问标志,则直接可以退回,然后继续访问第1个未访问的子节点。
        /// 下面的算法其实就是利用这种思想,只是不是直接设置标志,而是利用了数组指针的特性。
        /// 对于左子右兄弟的表达是任意叉树也可以实现,只是退回遍历方法不同而已(更简单).
        /// 如果采用的是K个孩子指针变量的表示孩子节点的方式,也是适用的,只是需要默认一个访问逻辑顺序即可.
        /// 注意:这里其实采用的是先父后子的访问顺序,如果需要先子后父,也是可以的,需要增加一个子访问完成退回标记,稍稍修改
        /// 一下代码即可.
        /// </summary>
        /// <param name="ListCurrNode">遍历访问者</param>
        public void ListAll1(Action<TreeNode> ListCurrNode)
        {
            int theQuitFrom = -1;//-1表示从父节点来,0-n表示从第k个孩子回来.
            TreeNode theCurrNode = Root;
            while (theCurrNode != null)
            {
                TreeNode theTmp = null;
                if (theQuitFrom < 0)//刚从父节点过来(theQuitFrom=-1)
                {
                    ListCurrNode(theCurrNode);
                    //从父节点过来时,访问第1个孩子(索引为0).
                    if (theCurrNode.Children.Count > 0)
                    {
                        theTmp = theCurrNode.Children[0];
                    }
                    else
                    {
                        theTmp = null;
                    }
                }
                else //从孩子节点遍历退回来,则去下一个孩子节点。
                {
                    if (theQuitFrom + 1 < theCurrNode.Children.Count)
                    {
                        theTmp = theCurrNode.Children[theQuitFrom + 1];
                        theQuitFrom = -1;
                    }
                    else//孩子节点访问完成,theTmp置空,继续执行后退策略.
                    {
                        theTmp = null;//如果要先子后父,需要在这里做标记
                    }
                }
                if (theTmp == null) //如果theTmp为空,则表示无法继续向下遍历,需后退访问兄弟节点
                {
                    //如果当前节点是root,表示已经需从root退回,则表示整个树遍历完成,
                    //这里也保证了GetChildrenIndex不会返回-1的情况.
                    if (theCurrNode == Root)
                        break;
                    theQuitFrom = GetChildrenIndex(theCurrNode.Parent, theCurrNode);
                    theCurrNode = theCurrNode.Parent;
                }
                else //不为空,则将theTmp节点作为当前节点进行访问。
                {
                    //这种情况下,theQuitFrom一定是-1.因为初始为-1,只有退回的时候才会改变这个值,
                    //如果退回有下一个兄弟可访问,则theQuitFrom一定会被设置为-1,如果没有,则只能继续
                    //退.如果能继续访问,theQuitFrom一定保持着-1.
                    theCurrNode = theTmp;
                }
            }

        }
        /// <summary>
        /// 获取孩子节点在父节点中的位置.
        /// </summary>
        /// <param name="Parent"></param>
        /// <param name="Child"></param>
        /// <returns></returns>
        private int GetChildrenIndex(TreeNode Parent, TreeNode Child)
        {
            for (int i = 0; i < Parent.Children.Count; i++)
            {
                if (Parent.Children[i] == Child)
                {
                    return i;
                }
            }
            //实际上这里放回-1是没法执行的.
            return -1;
        }
    }
本文参考了优快云网友的文章: http://blog.youkuaiyun.com/acrazer/article/details/4454508
Ubuntu环境下rknn-toolkit2的安装与兼容性解析 本文详细解析了在Ubuntu系统上安装瑞芯微rknn-toolkit2工具链的完整流程与关键注意事项。文章重点剖析了rknn-toolkit2与旧版rknn-toolkit的核心兼容性问题,强调两者在API、模型格式及运行时库上互不兼容,并推荐使用Conda虚拟环境进行隔离管理,为RK3566、RK3588等开发板的AI模型部署提供清晰的实践指南。 阅读详情

相关推荐

别再套用星形公式了!三角形接法PMSM的FOC控制,扇区判断与作用时间推导全解析

本文深入解析三角形接法永磁同步电机(PMSM)的FOC控制技术,重点探讨30度相位差对SVPWM扇区判断与电压矢量作用时间的影响。通过数学推导与实验验证,详细讲解修正后的扇区划分规则、作用时间计算公式优化方法,并提供可直接移植到STM32的代码实现,帮助工程师解决三角形接法特有的相电流重构与同步采样难题。

weixin_30689307的博客 469

Api返回调用结构

响应调用: namespace Common.Web { public class ResParameter<T> { /// <summary> /// 接口响应码 /// </summary> public ResponseCode code { get; set...

努力努力再努力Joanna 527

海康威视门禁考勤设备数据对接实战:从被动推送到主动拉取

本文深入探讨了海康威视门禁考勤设备数据对接的两种核心方案:HTTP推送与SDK主动拉取。文章对比了两种方式的适用场景、技术实现与优缺点,为开发者提供了从设备配置、代码编写到工程化部署的完整实战指南,帮助读者根据项目规模、网络环境及数据稳定性要求,做出最合适的技术选型。

weixin_29284657的博客 670

程序设计 树基础

一个没有固定根结点的树称为无根树有n个结点,n−1条边的连通无向图无向无环的连通图任意两个结点之间有且仅有一条简单路径的无向图任何边均为桥的连通图没有圈,且在任意不同两点间添加一条边之后所得图含唯一的一个圈的图在无根树的基础上,指定一个结点称为根,则形成一棵有根树有根树在很多时候仍以无向图表示,只是规定了结点之间的上下级关系,详见下文。森林(forest):每个连通分量(连通块)都是树的图。按照定义,一棵树也是森林。生成树(spanning tree)

小嗷犬的博客 1270

CIC-IDS数据集特征介绍

###1、简介 通信安全机构(CSE)与加拿大网络安全研究所(CIC)合作项目,该项目对自1998年以来现有的11个数据集的评估表明,大多数数据集(比如经典的KDDCUP99,NSLKDD等)已经过时且不可靠。其中一些数据集缺乏流量多样性和容量,一些数据集没有涵盖各种已知的攻击,而另一些数据集将数据包有效载荷数据匿名化,这不能反映当前的趋势。有些还缺少特征集和元数据。 CIC-IDS-2017数据集包含良性和最新的常见攻击,类似真实世界数据(PCAPs)。 它的数据采集截至2017...

蓝亚之舟的博客 3万+

matebookego win11 arm 系统安装安卓子系统

一般的x86电脑如果安装android子系统,运行安卓子系统,由于要将android arm代码转译为x86代码,所以效率不一定高,但是如果电脑是arm架构的,通过安卓子系统运行android的程序执行效率就会 高不少,本文参考,都是在win11 home版本下的。两者跑分在cpu上差不太多了,大约是枭龙855的水平了,这个水平的子系统就有一定的实用性了,玩个一般游戏,刷个抖音都很流畅的。启动子系统后,点击左上角的设置,启用 “开发人员模式”。然后就可以再通运运行华为应用商店来进行安装其它应用了。

babytiger的专栏 1万+

C++ 树

树是一种特殊的图,它必须为连通图,且每个结点最多只能有一个父结点。下图展示了一棵树树还分为有根树和无根树,有根树就是有根结点的树,而无根树就是没有根结点的树。

dengzjh92的博客 1821

DeepCAD: 使用深度自监督学习技术在Python中进行钙成像去噪的全面指南

钙成像是一种用于观察神经活动的技术,通过检测细胞内钙离子的变化来推断神经元的活动。由于其高时空分辨率和对活体组织的适应性,钙成像已经成为神经科学研究中的重要工具。然而,钙成像数据往往伴随着各种噪声,这些噪声可能来自于设备、生物样本或环境。为了获得准确的神经活动信息,去噪是非常关键的。深度自监督学习是一种使用未标记数据进行训练的机器学习方法。与传统的监督学习不同,它不需要大量的标记数据,而是通过学习数据的内部结构和模式来提取有用的特征。DeepCAD是一个基于深度自监督学习的钙成像去噪工具。

qq_38334677的博客 758

链表

链表的基本介绍 要想保存多个对象,首先的方法是对象数组,同时如果该数组可以保存任意对象,那应该是Object型的数组。Object[] data = new Object[3];。但是数组是定长的线性结构。如果数据的数量不确定,那就很难用数组来表示了。 类似火车的车厢的设计模式,动态的进行车厢的挂载,那么假设每一节车厢只保留一个数据,并不受内存的限制,就可以证明解决了数据的长度问题。火车车厢不能只...

mrbacker的博客 476

3.详解Labview串口通讯--从串口线连接到串口通讯保姆级教程

本文非常详细的介绍了使用Labview实现串口通讯,读完题主这篇文章,即使你是今天刚下载的Labview,也能熟练的连接并驱动串口执行,接下来和我一起学习下,记得关注并点赞不迷路

关注我,更多技术问题欢迎私聊~ 1万+

【系统移植】 移植主线U-Boot(v2024.01-rc3)到RK3399

[系统移植] 移植主线U-Boot(v2024.01-rc3)到RK3399

Systemcall名屋 1004

《算法导论》笔记 第10章 10.4 有根树的表示

【笔记】 【练习】

Azarath Metrion Zinthos 779

部署与可视化系统:移动端落地保姆级教程:YOLOv8 转换为 NCNN 并封装进 Android App 调用摄像头实时检测

本文介绍了在移动端部署YOLOv8模型的最佳实践。通过实测数据对比,采用NCNN框架在骁龙865设备上可实现35+FPS的实时推理性能。文章详细分析了NCNN相比TFLite、MNN等框架的优势,包括更高的ARM CPU性能、更优的Vulkan GPU加速和更小的模型体积。同时提供了从PyTorch模型到NCNN格式的完整转换流程,包括FP16优化和INT8量化方法,并重点解析了YOLOv8特有的输出格式处理要点。建议开发者先在Python环境验证NCNN推理流程,再部署到Android平台,以确保最佳性能

ZXSXJ的博客 209

邓俊辉数据结构与算法学习笔记-第五章

文章目录树aa1 树a2 应用a3 有根树a4 有序树a5 路径a6 连通图无环图a7 深度层次b 在计算机中表示b1 树的表示b2 父节点b3 孩子节点b4 父亲孩子表示法b5 长子兄弟表示法c 二叉树c1 二叉树概述c2 真二叉树c3 描述多叉树 day21 树 a a1 树 tree将二者的优点结合起来,树是列表的列表List< List> a2 应用 层次关系的表示:表达式(如RPN),文件系统,URL,… a3 有根树 a4 有序树 a5 路径 a6 连通图无环图 根据上图右半部

xiaodidadada的博客 483

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

算法导论笔记(四)

第十章:基本数据结构 摘要   本章介绍了几种基本的数据结构,包括栈、队列、链表以及有根树,讨论了使用指针的简单数据结构来表示动态集合。本章的内容对于学过数据结构的人来说,没有什么难处,简单的总结一下。 1、栈和队列   栈和队列都是动态集合,元素的出入是规定好的。栈规定元素是先进后出(FILO),队列规定元素是先进先出(FIFO)。栈和队列的实现可以采用数组和链表进行实现。...

weixin_30736301的博客 333

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

tarjan算法_【朝夕的ACM笔记】树上问题-最近公共祖先-倍增算法

【朝夕的ACM笔记】目录与索引最近公共祖先-倍增算法一、基本概念最近公共祖先问题:对于给定的一颗有根树,求其两个节点的最近公共祖先。祖先:节点本身、节点的父亲、节点父亲的父亲……都是该节点的祖先。公共祖先:两个节点共同的祖先。最近公共祖先(Lowest Common Ancestor)即LCA:距离根最远的公共祖先(也是深度最大的公共祖先)。*LCA的重要性质:①若 是 的祖先,则 。②若 ...

weixin_39748858的博客 160

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

用数组实现树的存储遍历【复习笔记】

树是由 n(n≥0)个有限节点组成的一个具有层次关系的集合。当 n=0 时,称为。在一棵非空树中,有且仅有一个特定的节点称为;其余节点可分为 m 个互不相交的有限集 T1、T2、…、Tm,其中每个集合本身又是一棵树,并且称为根结点的子树因此,树是定义的:一个节点拥有的子树个数称为该节点的度。度为 0 的节点称为叶子节点或终端节点;度不为 0 的节点称为分支节点。:树中节点的最大度数称为树的度。:树中两个结点之间的路径是由这两个结点之间所经过的结点序列构成的,路径长度为序列中 边的个数。

2402_87252674的博客 718

【算法学习笔记】二叉树的最近公共祖先——为什么说二叉树的遍历顺序很重要?

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(3节点5和节点1的最近公共祖先是节点3。5节点5和节点4的最近公共祖先是节点5。因为根据定义最近公共祖先节点可以为节点本身。1。

xiaoy23333的博客 320

算法导论笔记:数据结构

下中位数、栈、队列、链表、有根树

danxutj的博客 119

INT202笔记整理

今天看别的课的时候想起来好像以前学过rsa然后发现这门课只发了例题笔记没发,补发一下*

Scabbards_的博客 1301

数据结构与算法——二叉树(一) 学习笔记

一、 树 树(Tree),用来按照层次关系,组织一系列数据项的数据结构。兼顾了向量和列表的静态、动态操作优点,属于半线性结构 1.1 树 有根树 指定任意节点r作为根后,T即称作有根树(rooted tree)。相对于T,TiT_iTi​ 称作以rir_iri​ 为根的子树,记作Ti=subtree(ri)T_i=subtree(r_i)Ti​=subtree(ri​) 任一节点r在通往树根沿途所...

提小莫的寂寥的博客 689

算法学习笔记 - 倍增

前言 倍增,字面意思就是“成倍增长”。这是指我们在进行递推时,如果状态空间很大,通常的线性递推无法满足时间与空间复杂度的要求,那么我们可以通过成倍增长的方式,只递推状态空间中在 2 的整数次幂位置上的值作为代表。当需要其他位置上的值时,我们通过“任意整数可以表示成若干个2的次幂项的和”这一性质,使用之前求出的代表值拼成所需的值。所以使用倍增算法也要求我们递推的问题的状态空间关于2的次幂具有可划分行 ...

haobowen的博客 3433

数据结构(一):栈、队列、链表、有根树

《算法导论》笔记 1 栈(stack) 概念 栈和队列都是动态集合,栈实现的是后进先出(last-in,first-out,LIFO),删除操作作用于最近插入的元素 操作 栈上的INSERT操作称为压入(PUSH),DELETE操作称为弹出(POP) 当栈中不包含任何元素,则栈是空的(empty),对空栈执行弹出操作,称为栈下溢(underflow),如果栈内元素超过所分配内存上限,则会出现栈上溢(overflow) 三种栈操作的时间复杂度都为O(1) // 用数组实现栈 #include<i.

积流成河 249

入门者笔记·LCA(链式前向星)

LCA(最近公共祖先) LCA(Least Common Ancestors),即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先。 所谓倍增,就是按2的倍数来增大,也就是跳 1,2,4,8,16,32 …… 不过在这我们不是按从小到大跳,而是从大向小跳,即按……32,16,8,4,2,132,16,8,4,2,1来跳,如果大的跳不过去,再把它调小。这是因为从小开始跳,可能会出现“...

weixin_43918350的博客 398

算法笔记:树和二叉树基础

专题:树和二叉树基础 内容来源:《算法竞赛入门经典》(第2版)+网上资料整理汇总 一、引入 1. 树是一种非线性的数据结构,用它能很好地描述有分支和层次特性的数据集合。树型结构在现实世界中广泛存在,如社会组织机构的组织关系图就可以用树型结构来表示。树在计算机领域中也有广泛应用,如在编译系统中,用树表示源程序的语法结构。在数据库系统中,树型结构是数据库层次模型的基础,也是各种索引和目录的主要组

cr496352127的博客 1127
上一篇: 算法笔记(选择算法)
下一篇: 算法笔记(红黑树)
广州接入
广州接入 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄24年 2224粉丝 731原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值