《Thinking In Algorithm》10.树的三种遍历(递归与非递归实现)

【十万字拆解】从零开始实现GPT-2(完整版) 本文是一篇 14 万字、从零硬核实现 GPT 的保姆级指南。内容全面覆盖四个阶段:①从最基础的 Bigram 语言模型切入,跑通数据处理与训练闭环;②仿照 Transformer 架构,深度研究 Multi-Head Attention、残差网络、LayerNorm 及 Dropout 的底层数学与代码实现;③从零构建BPE 分词器,对齐 GPT-2 规范;④从头搭建 GPT-1/2 工业级预训练流程,包含混合精度、梯度累积等十余项硬件级工程调优,并在 AutoDL 算力平台上从0开始训练!适合所有层次! 阅读详情

1:深度优先


1.1:前序遍历

  1. Visit the root.
  2. Traverse the left subtree.
  3. Traverse the right subtree.
如下图:
Pre-order: F, B, A, D, C, E, G, I, H
伪代码:
preorder(node)
  if node == null then return
  visit(node)
  preorder(node.left) 
  preorder(node.right)
iterativePreorder(node)
  parentStack = empty stack
  parentStack.push(null)
  top =  node 
  while ( top != null )
      visit( top )
      if ( top.right != null ) 
          parentStack.push(top.right)
      if ( top.left != null ) 
          parentStack.push(top.left)
      top = parentStack.top();
      parentStack.pop();

1.2:中序遍历

  1. Traverse the left subtree.
  2. Visit root.
  3. Traverse the right subtree.
In-order: A, B, C, D, E, F, G, H, I
伪代码:
inorder(node)
  if node == null then return
  inorder(node.left)
  visit(node)
  inorder(node.right)
iterativeInorder(node)
  parentStack = empty stack
  while (not parentStack.isEmpty() or node ≠ null)
    if (node ≠ null)
      parentStack.push(node)
      node = node.left
    else
      node = parentStack.pop()
      visit(node)
      node = node.right

1.3:后序遍历

  1. Traverse the left subtree.
  2. Traverse the right subtree.
  3. Visit the root.
Post-order: A, C, E, D, B, H, I, G, F
伪代码
postorder(node)
  if node == null then return
  postorder(node.left)
  postorder(node.right)
  visit(node)
iterativePostorder(node)
  parentStack = empty stack  
  lastnodevisited = null 
  while (not parentStack.isEmpty() or node ≠ null)
    if (node ≠ null)
      parentStack.push(node)
      node = node.left
    else
      peeknode = parentStack.peek()
      if (peeknode.right ≠ null and lastnodevisited ≠ peeknode.right) 
        /* if right child exists AND traversing node from left child, move right */
        node = peeknode.right
      else
        parentStack.pop() 
        visit(peeknode)
        lastnodevisited = peeknode

1.4:java代码实现三种遍历

树的结构是
                                            10
                                           /   \
                                          5     12
                                        /   \   
                                     4       7 
代码中我主要解释下让我一直纠结的递归法了,总是对递归法执行的顺序有疑惑。详细可以看《Thinking In Algorithm》09.彻底理解递归

public class Preorder{	
	/*******************************递归法****************************/
	//递归前序遍历		print:10,5,4,7,12
	public static void preorder(TNode node){
		if(node!=null){
			System.out.println(node.getValue()) ;
			preorder(node.getLeft()) ;
			preorder(node.getRight()) ;
		}
	}
	//递归中序遍历		print: 4,5,7,10,12
	public static void inorder(TNode node){
		if(node!=null){
			inorder(node.getLeft()) ;
			System.out.println(node.getValue()) ;
			inorder(node.getRight()) ;
		}
	}
	//递归后序遍历		print: 4,7,5,12,10
	public static void postorder(TNode node){
		if(node!=null){
			postorder(node.getLeft()) ;
			postorder(node.getRight()) ;
			System.out.println(node.getValue()) ;
		}
	}
	
	/*******************************非递归*****************************/
	//非递归前序遍历		print:10,5,4,7,12
	public static void iterativePreorder(TNode node){
		MyStack parentStack = new MyStack() ;
		parentStack.push(node) ;
		while(!parentStack.isEmpty()){
			TNode temp = parentStack.getFirst().getValue() ;
			System.out.println(temp.getValue()) ;
			parentStack.pop() ;
			if(temp.getRight()!=null){ parentStack.push(temp.getRight()) ;}
			if(temp.getLeft()!=null){ parentStack.push(temp.getLeft()) ;}
		}
	}
	//非递归中序遍历		print: 4,5,7,10,12
	public static void iterativeInorder(TNode node){
		MyStack  mystack = new MyStack() ;
		while(!mystack.isEmpty()||node!=null){
			if(node!=null){
				mystack.push(node) ;
				node = node.getLeft() ;
			}else{
				node = mystack.pop().getValue() ;
				System.out.println(node.getValue()) ;
				node = node.getRight() ;
			}
		}
	}
	//非递归后序遍历		print: 4,7,5,12,10
	public static void iterativePostorder(TNode node){
		MyStack  mystack = new MyStack() ;
		TNode temp = null ;
		TNode peeknode = null ;
		while(!mystack.isEmpty()||node!=null){
			if(node!=null){
				mystack.push(node) ;
				node = node.getLeft() ;
			}else{
				peeknode = mystack.getFirst().getValue() ;
				if(peeknode.getRight()!=null&&temp!=peeknode.getRight()){
					node = peeknode.getRight() ;
				}else{
					mystack.pop() ;
					System.out.println(peeknode.getValue()) ;
					temp = peeknode ;
				}
			}
		}
	}
	
	public static void main(String args[]){
		MyTree mytree = new MyTree() ;
		mytree.insert(10) ;
		mytree.insert(5);
		mytree.insert(12);
		mytree.insert(4);
		mytree.insert(7);
		
		preorder(mytree.getRoot()) ;
		inorder(mytree.getRoot()) ;
		postorder(mytree.getRoot()) ;
		
		iterativePreorder(mytree.getRoot()) ;
		iterativeInorder(mytree.getRoot()) ;
		iterativePostorder(mytree.getRoot()) ;
	}
}
/*****************二叉树的实现****************/
class TNode{
	private int value ;
	private TNode left ;
	private TNode right ;
	
	public TNode(int value){ this.value = value ;}
	public void setLeft(int value){ this.left = new TNode(value) ;}
	public void setRight(int value){ this.right = new TNode(value) ;}
	public TNode getLeft(){ return this.left ;}
	public TNode getRight(){ return this.right ;}
	public int getValue(){ return this.value ;}
}
class MyTree{
	private TNode root ;
	
	public void setRoot(int value){ this.root = new TNode(value) ;}
	public TNode getRoot(){ return this.root ;}
	public void insert(int value){
		TNode x = this.root ;
		TNode y = null ;
		while(x!=null){
			y = x ;
			if(value<x.getValue()){ x = x.getLeft() ;}
			else{ x = x.getRight() ;}
		}
		
		if(y == null){ setRoot(value) ;}
		else if(value<y.getValue())
		{ y.setLeft(value) ;}
		else{ y.setRight(value) ;}
	}
}

/*****************栈的实现****************/
class StackNode{  
        public TNode item ;  
        public StackNode next ;  
		
        public StackNode(){ ;}
		public StackNode(TNode item){ this.item = item ;}
        public TNode getValue(){ return item ;}  
}  
class MyStack{  
    int N ; //size of myStack  
    StackNode first ; // the top of stack  
      
      
    //size of mystack  
    public int size(){ return N ;}  
      
    //empty or not  
    public boolean isEmpty(){ return N==0 ;}  
	
	public StackNode getFirst(){ return this.first ;}
      
	public void push(TNode item){
		if(isEmpty()){
			first = new StackNode() ;  
			first.item = item;  
			N++; 
		}else{
			StackNode oldfirst = first;  
			first = new StackNode() ;  
			first.item = item;  
			first.next = oldfirst;  
			N++; 
		}
		
	}
    public StackNode pop(){
		StackNode top = first ;
        first = first.next;            // delete first node  
        N--;  
		return top ;
	}
}


2.广度遍历

广度遍历比较简单,就是层次遍历
                
伪代码
levelorder(root)
  q = empty queue
  q.enqueue(root)
  while not q.empty do
    node := q.dequeue()
    visit(node)
    if node.left ≠ null then
      q.enqueue(node.left)
    if node.right ≠ null then
      q.enqueue(node.right)


Java递归遍历树的实现与应用 树的遍历分为前序遍历、中序遍历和后序遍历。这些遍历方法对应于访问节点和子节点的顺序不同。前序遍历先访问根节点,然后是子节点;中序遍历先访问左子树,然后是根节点,最后是右子树;后序遍历则是先访问子节点,最后访问根节点。// 树遍历的方法签名示例// 先访问节点,再递归遍历子节点// 先递归遍历左子树,然后访问节点,最后递归遍历右子树// 先递归遍历子节点,最后访问节点这些方法的具体实现将在下一章详细讨论。 阅读详情

相关推荐

从翼型到湍流:用生活化案例图解空气动力学核心概念(中英双语版)

本文通过飞机机翼、F1赛车、高尔夫球等生活化案例,图解空气动力学核心概念。深入浅出地解释了攻角如何产生升力、边界层与流动分离如何影响阻力、马赫数如何划分速度世界,以及涡流与湍流的特性与应用。文章还介绍了计算流体动力学(CFD)这一现代数字风洞工具,帮助读者直观理解这些塑造现代交通与运动设计的无形之力。

metaverse5vr的博客 475

【算法】树的遍历-递归遍历【前序,中序,后续】

大家好,我是程序员walker 一个持续学习,分享干货的博主 关注公众号【I am Walker】,一块进步 树的遍历一般分为两种形式,有递归遍历和迭代方式 这里介绍的是递归方式 递归的定义: 程序调用自身的编程技巧称为递归( recursion)。 递归作为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少.

Think_and_work的博客 2925

即插即用!5分钟为你的SNN模型添加频谱注意力(DCT-SA模块实战)

本文介绍了如何为脉冲神经网络(SNN)快速集成即插即用的DCT-SA频谱注意力模块。该模块利用离散余弦变换(DCT)在频率域自适应加权特征,能有效提升模型对纹理、边缘的感知能力,并在CIFAR10-DVS等数据集上实现分类精度提升与脉冲发放率下降。文章以SpikingJelly框架和ResNet19为例,提供了详细的代码实现、集成步骤及参数调优实战指南。

kotlin6android的博客 609

使用递归的方式遍历树

使用递归的方式遍历树 树的前序遍历 public class TreeTest { public static void main(String[] args) { TreeTest treeTest = new TreeTest(); TreeNode head = new TreeNode(1,new TreeNode(2),null); List<Integer> list = treeTest.inorderTraversal(he

qq_46589658的博客 1573

Infineon MOSFET开关损耗计算实战指南

本文是英飞凌MOSFET开关损耗计算的实战指南。针对MOSFET发热问题,文章深入剖析了开关损耗的产生机理,并基于Infineon数据手册的关键参数,手把手推导了开通与关断损耗的工程计算公式。同时,指南强调了栅极电阻、寄生参数等实际因素对损耗的影响,并提供了从理论计算到实测优化的完整路径,帮助工程师精准评估与优化电源设计。

weixin_29212867的博客 442

数字取证双雄:Passware Kit Forensic 与 ElcomSoft 在实战场景下的能力边界解析

本文深入解析了Passware Kit Forensic与ElcomSoft在数字取证实战中的能力边界,涵盖Windows、macOS、iOS和Android系统的密码恢复与数据提取技术。通过真实案例对比两款工具在硬件加速、分布式计算及云取证等场景下的表现差异,为取证专家提供关键决策参考。特别探讨了密码恢复软件在加密设备突破中的核心作用。

weixin_30342209的博客 399

数据结构6.2——树的遍历(递归/非递归)

遍历一棵树实际上就是把树的结点排成一个线性序列的过程。

clllllz_的博客 1909

Vue 10分钟入门VR全景显示 基于photo-sphere-viewer

文章目录前言一、引入photo-sphere-viewer?二、使用步骤1.引入库2.声明容器3.内容加载4.全部代码总结 前言 由于工作的需求,要实现全景图片的展示与预览,本来以为会是一个很难的内容,没想到使用现成的组件photo-sphere-viewer就可以轻松实现,上手只需要10分钟! 一、引入photo-sphere-viewer? 可以直接通过npm进行引入 npm install photo-sphere-viewer 二、使用步骤 1.引入库 photo-sphere-viewer

YIGE_MO的博客 5866

递归算法遍历树

1.牢记递归三步曲,运用时搞清楚这三步2.多练习多测试。

梁白开的博客 294

司法AI系统的架构设计:法律知识图谱如何辅助智能庭审?架构师亲测

简单来说,法律知识图谱是一种采用图数据结构(节点Node + 边Edge/关系Relation)来组织和表达法律领域知识的语义网络。它以。

AI 算法实战派 1088

科研绘图系列:R语言绘制差异蝴蝶图(Butterfly Chart)

科研绘图系列:R语言蝴蝶图(Butterfly Chart)

专注生信领域 1391

递归遍历树结构数据(js,vue)

【代码】递归遍历树结构数据(js)

weixin_45776308的博客 5607

运维颠覆!一文解锁AI赋能运维实战秘籍,效率飙升!

将AI应用于运维工作是一场极具价值的变革,从故障预测与诊断到自动化任务执行,再到资源管理优化,AI都展现出巨大潜力。尽管在实践过程中会面临数据质量、模型复杂性等挑战,但通过合理的技术选型和解决方案,我们能够充分挖掘AI的优势,实现运维工作的高效、智能转型。持续探索和创新AI在运维领域的应用,将为企业的数字化发展提供坚实保障。在科技飞速发展的当下,运维领域正经历着深刻变革,AI的融入成为提升运维效率与质量的关键。本文将深入实战,带你领略AI如何在运维各环节大显身手,让你的运维工作开启智能高效新模式。

探索云原生与智能化驱动下的安全运维新范式。关注DevSecOps、可观测性、AIOps等前沿领域,与您共赴技术前沿。 401

《Thinking In Algorithm》09.彻底理解递归

转自:http://blog.csdn.net/speedme/article/details/21654357 递归真的非常非常重要!!! 我们直接从例子开始吧! 一:简单实例 1.阶乘的实现 写个函数实现   N! = N × (N-1) × (N-2) × ... × 2 × 1 [java] view plain copy  p

春风十米的博客 369

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

WINCC7.3破解文件

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

雅思常用习语词汇积累

常见雅思习语词汇总结

工匠精神coding,终生学习 529

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

二叉树遍历之后序遍历(非递归、递归)入门详解

二叉树后序遍历不如先序遍历简单,是相对最复杂的一种遍历方法。访问结点的次序是:“左—>右—>根”,也就是首先访问左子树,之后访问右子树,最后访问树根。对于左、右子树而言,其访问的次序依然是“左—>右—>根”。也就是说,对于每一棵子树,都是最后访问树根。...

sunnyoldboy博客 3万+

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

二叉树三种遍历方式(递归和非递归)

树形结构是一类重要的非线性数据结构。其中以树和二叉树是最为常用。 二叉树有四种遍历顺序:先序遍历(前序遍历),中序遍历,后序遍历,层序遍历。 这三种遍历的方式其实是由遍历的根结点的顺序来定义的。 先序遍历:先访问根结点,再遍历它的左子树,最后遍历它的右子树。 中序遍历:先遍历左子树,然后访问根结点,最后遍历它的右子树。并且在遍历左右子树的时候。仍然是先遍历左子树,然后访问根节点,最后遍历右...

不期而遇 2675

C语言-非递归完成树的三种遍历

学习两天半,我终于明白了非递归遍历树,赶快来学一学!!!

Jaye513的博客 1138

【数据结构】二叉树的遍历递归算法详解

int val;}BTNode;

2302_76305195的博客 3221

数据结构学习——树形结构之递归遍历二叉树

本文为大家介绍了数据结构学习——树形结构之递归遍历二叉树,希望对你有帮助~~

weixin_53919192的博客 3623

树的三种遍历方式(都是递归)

树的遍历

mohanhan13131的博客 835

树的三种遍历非递归操作

1.前序遍历 前序遍历是:根节点-左节点-右节点;和深度优先遍历一致,这里可以参照之前写的 BFS(广度优先遍历)和DFS(深度优先遍历) 其文章链接:https://blog.csdn.net/sdshdutx/article/details/106721827 2.中序遍历 中序遍历是:左子树-根节点-右子树(每一个子树都满足这种访问方式),如下所示:输出为5->2->6->1->4 那么我们在经过某一个子根节点时前面节点不能释放, 因为需要遍历到其底部,才算完成左边子树的遍

sdshdutx的博客 1851

树的四种遍历方式(递归与非递归实现c++&java)

树的遍历: 1.前序遍历 2.中序遍历 3.后序遍历 4.层序遍历 1.前序遍历 前序遍历即DLR,先访问根节点再访问左子树,再访问右子树,因此需要遍历和回溯 递归:递归遍历左子树,遍历的同时,用list保存节点的值用s保存遍历过的节点,走到底之后就回溯,访问上一个节点的有节点,重复以上过程,直到访问到最后一个节点(左右都为空) java: class Solution { List<Integer> list=new ArrayList<Int...

m0_51474171的博客 879

JavaScript:递归遍历树

The ability to traverse a tree is an important basic foundational concept. A tree is a data structure with a collection of nodes with a hierarchical pattern. Each node is its own data structure. A tre...

weixin_26750481的博客 1423

二叉树的递归/层序遍历

回顾写法二,我们每向下遍历一层,就给 depth 加 1,可以理解为每条树枝的权重是 1,二叉树中每个节点的深度,其实就是从根节点到这个节点的路径权重和,且同一层的所有节点,路径权重和都是相同的。知道节点的层数是个常见的需求,比方说让你收集每一层的节点,或者计算二叉树的最小深度等等。这种写法就可以记录下来每个节点所在的层数,可以解决诸如二叉树最小深度这样的问题,是我们最常用的层序遍历写法。那么假设,如果每条树枝的权重和可以是任意值,现在让你层序遍历整棵树,打印每个节点的路径权重和,你会怎么做?

xiangfengweixiaojie的博客 565

阶段总结-树与递归

两种定义形式:链表定义和数组定义二叉树的定义N叉树的定义。

qq_41662142的博客 125
上一篇: 《Thinking In Algorithm》09.彻底理解递归
下一篇: java中Map,List与Set的区别
SpeedMe
博客等级 码龄15年 779粉丝 142原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值