后序遍历

非线性数据结构——树

微笑、不失礼 提交于 2020-02-08 16:52:52
树 非线性数据结构定义:也就是每个元素可以有多个前驱和后继。树是一种非线性结构。它可以有两种定义。 第一种:树是n(n>=0, n为0时,称为空树 )个元素的集合,它只有 一个特殊的没有前驱的元素 ,这个元素成为树的 根(root) ,而且 树中除了根节点外,其余的元素都只能有一个前驱,可以有0个或者多个后继。 第二种递归定义:树T是n(n>=0,n为0时,称为空树)个元素的集合,它有且只有一个特殊元素根,剩余元素都可以被划分为M个互不相交的集合T1,T2,T3……、Tm,而每一个集合都是树,称为T的子树subtree,同时,子树也有自己的根。 维基百科是这样定义的: 树中的概念 结点: 树中的数据元素,也就是上图中的,A,B,C,D,E,F,G…… 结点的度degree :节点拥有的子树的数目称为度,记作d(v)。 叶子结结: 节点的度为0,称为叶子节点leaf,终端节点,末端节点。 分支结点: 节点的度不为0,称为非终端节点或分支节点。 分支: 节点之间的关系。 内部节点: 除根节点外的分支节点,当然也不包括叶子节点。 树的度: 树内各节点的度的最大值,比如下面这个图D节点的度最大为3,所以树的度数就是3. 孩子(儿子child)节点: 节点的子树的根节点成为该节点的孩子。 双亲(父parent)节点: 一个节点是他各子树的根节点的双亲。 兄弟(sibling)节点:

二叉树遍历算法

泪湿孤枕 提交于 2020-02-07 15:51:20
二叉树 是树(Tree)这一数据结构中非常重要的子类,其中每一个节点最多存在两个子节点,在代码中表示就是,除了本身的 Data 值,还会带有 Left 和 Right 子节点。如下图所示,用形如图中的结构构成了整棵树。 任何一种数据结构,都会存在遍历的顺序问题,比如链表,堆栈等等;二叉树这种数据结构也有遍历的顺序,由于其非线性的结构特征,遍历时的顺序有这三种, 前序(pre-order),中序(in-order),后序(post-order) 。下面依次介绍一下: 1 前序(pre-order)遍历 基本的原则是 “根 -> 左 -> 右” ,重复直到整棵树的节点被浏览一遍。 1.1 Recursive 版本: 1 def preOrder( self, treenode ): 2 # Recursive version 3 if treenode == None: 4 return 5 print treenode.data 6 self.preOrder( treenode.left ) 7 self.preOrder( treenode.right ) 这段代码非常好理解,它就是用“根 -> 左 -> 右”的定义方式来写的,迭代调用,直至没有节点可以访问。 print treenode.data # 打印访问节点(根)的值 self.preOrder( treenode )

数据结构之二叉树遍历

允我心安 提交于 2020-02-07 15:50:32
一、树的遍历操作 树的遍历:从根节点出发,按照某种次序访问树中所有结点,使得每个结点被访问一次且仅被访问一次。 遍历的实质为将树结构(非线性结构)转换为线性结构。 树通常有前序(根)遍历、后序(根)遍历和层序(次)遍历三种方式。 前序遍历: 树的前序遍历操作定义为: 若树为空,则空操作返回; 否则 (1)访问根结点;   (2)按照从左到右的顺序前序遍历根结点的每一棵子树 图中树的前序遍历序列为:A B D E H I F C G 树的后序遍历操作定义为: 若树为空,则空操作返回; 否则 ⑴ 按照从左到右的顺序后序遍历根结点的每一棵子树; ⑵ 访问根结点。 图中树的后序遍历序列: D H I E F B G C A 树的层序遍历操作定义为: 从树的第一层(即根结点)开始,自上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。 图中树的层序遍历序列: A B C D E F G H I 二、二叉树的遍历操作 前序(根)遍历: 若二叉树为空,则空操作返回; 否则: ①访问根结点; ②前序遍历根结点的左子树; ③前序遍历根结点的右子树。 图中二叉树的前序遍历序列:A B D G C E F 中序(根)遍历: 若二叉树为空,则空操作返回; 否则: ①中序遍历根结点的左子树; ②访问根结点; ③中序遍历根结点的右子树。 图中二叉树的中序遍历序列:D G B A E C F 后序(根

二叉树的代码实现 JAVA 版本

こ雲淡風輕ζ 提交于 2020-02-07 13:14:22
本文主要实现二叉树的简单功能: (1)二叉树的生成 (2)二叉树的遍历:前序遍历,中序遍历,后序遍历,层次遍历 (3)二叉树的删除 (3)判断节点是否存在的功能 package ds.tree; import ds.link.Node; import java.util.LinkedList; import java.util.Queue; /** * @author : cuantianhou 2019/12/17 */ public class BinaryTree <T extends Comparable<T>>{ private Node<T> root; private int capacity = 0; public T insert(T data){ /** * Step1: 如果该节点为空,将该节点设置为根节点,父节点为空,返回出入值 * * */ capacity++; if(root == null) { root = new Node<T>(data,null); return root.data; } /** * Step2:从根节点遍历,插入节点比当前节点小,把当前节点设置为左子节点,然后与左子比较, * 插入节点比当前节点大,把当前节点设置为右子节点,然后与右子比较,插入节点和当前节点相等 * 覆盖并返回当前值 **/ //父节点 Node<T>

【Python数据结构与算法笔记day36】7.2. 二叉树的遍历+深度优先遍历+ 广度优先遍历(层次遍历)

吃可爱长大的小学妹 提交于 2020-02-07 10:36:43
文章目录 7.2. 二叉树的遍历 二叉树的遍历 深度优先遍历 广度优先遍历(层次遍历) 7.2. 二叉树的遍历 二叉树的遍历 树的遍历是树的一种重要的运算。所谓遍历是指对树中所有结点的信息的访问,即依次对树中每个结点访问一次且仅访问一次,我们把这种对所有节点的访问称为遍历(traversal)。那么树的两种重要的遍历模式是深度优先遍历和广度优先遍历, 深度优先一般用递归,广度优先一般用队列。一般情况下能用递归实现的算法大部分也能用堆栈来实现。 深度优先遍历 对于一颗二叉树,深度优先搜索(Depth First Search)是沿着树的深度遍历树的节点,尽可能深的搜索树的分支。 那么深度遍历有重要的三种方法。这三种方式常被用于访问树的节点,它们之间的不同在于访问每个节点的次序不同。这三种遍历分别叫做先序遍历(preorder),中序遍历(inorder)和后序遍历(postorder)。我们来给出它们的详细定义,然后举例看看它们的应用。 先序遍历 在先序遍历中,我们先访问根节点,然后递归使用先序遍历访问左子树,再递归使用先序遍历访问右子树 根节点->左子树->右子树 def preorder ( self , root ) : """递归实现先序遍历""" if root == None : return print root . elem self . preorder (

二叉树遍历

不羁岁月 提交于 2020-02-07 07:06:55
前序遍历:根->左->右 中序遍历:左->根->右 后序遍历:左->右->根 假设树节点的定义如下: struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; 递归版 //前序遍历 void preorderTraversalRecursion(TreeNode *node) { if(!node) return; cout << node->val << " ";//操作当前节点 preorderTraversalRecursion(node->left); preorderTraversalRecursion(node->right); } //中序遍历 void inorderTraversalRecursion(TreeNode *node) { if(!node) return; inorderTraversalRecursion(node->left); cout << node->val << " ";//操作当前节点 inorderTraversalRecursion(node->right); } //后序遍历 void postorderTraversalRecursion(TreeNode

LeetCode 145. 二叉树的后序遍历

守給你的承諾、 提交于 2020-02-07 07:06:34
给定一个二叉树,返回它的 后序 遍历。 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [3,2,1] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal 迭代: 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 * }; 9 */ 10 class Solution { 11 public: 12 vector<int> postorderTraversal(TreeNode* root) { 13 vector<int> ans; 14 if(!root) return ans; 15 stack<TreeNode*> nodeStack1,nodeStack2; 16 TreeNode* node; 17 nodeStack1.push(root); 18 while(

二叉树的遍历方式(内附视频讲解,各种语言的中序遍历代码实现)

点点圈 提交于 2020-02-06 03:54:34
二叉树之遍历方式 视频讲解 : 这是博主自己的视频,谢谢大家。 二叉树的遍历方式 b站链接: https://www.bilibili.com/video/av86745570 二叉树的性质 ,允许我们通过一个简单的递归算法来, 按序输出二叉搜索树中的所有关键字 ,这种算法叫做 遍历算法 。 为了讲解方便,先用伪代码顶着先,然后在用具体遍历代码, 具体的遍历代码是用中序遍历算法 >,因为中序遍历应用最广,面试最容易碰到。 那么按照顺序的不同,我们可以将遍历分为: 先序、中序、后序遍历算法 。 先序遍历 ( 根的关键字在其左右子树的关键字之前 ) : 1.对于单个节点而言,先父节点,自己的数据,然后左节点,然后右子节点 2.对于单个子树或者是树而言,先根,然后左子树,右子树。 (视频里面,比较清楚一点) 其实中序、先序、后序在递归的伪代码上, 唯一区别就在于输出语句的位置。 中序遍历 (根的关键字在其左子树的关键字和右子树的关键字之间) : 1.对于单个节点而言,先左子节点,自己,然后右子节点,最后父节点。 2.对于单个子树或者是树而言,先左子树,根节点,然后右子树。 后序遍历 (根关键字在其左右子树的关键字之后) : c语言的中序遍历代码实现,转载至csdn博主weixin_34302561的《二叉树中序遍历 (C语言实现)》博文,侵删: 相关链接:https://blog

树据结构与算法——二分搜索树 动画演示

…衆ロ難τιáo~ 提交于 2020-02-05 19:05:18
文章目录 一、二分查找法 二分查找法变变种:floor和ceil 二、二分搜索树 实现查找表的比较: 二分搜索树定义 插入元素 查找元素 三、二分搜索树的遍历 二分搜索树的遍历(深度优先遍历) 二分搜索树的层序遍历(广度优先遍历) 四、二分搜索树删除节点 删除最大值,最小值 删除任意节点 附录   二叉搜索树是用来解决查找问题的,在介绍二叉搜索树之前,先学习二分查找法。 一、二分查找法   二分查找法只能对于 有序数列 使用(排序后的数组),在中间找一个元素v如果不是v,这在<v和>v两部分查找,时间复杂度为O(logn),如下图所示: 二分查找代码: // 二分查找法,在有序数组arr中,查找target // 如果找到target,返回相应的索引index // 如果没有找到target,返回-1 template < typename T > int binarySearch ( T arr [ ] , int n , T target ) { // 在arr[l...r]之中查找target int l = 0 , r = n - 1 ; while ( r > l ) { //int mid = (l + r)/2; // 防止极端情况下的整形溢出,使用下面的逻辑求出mid int mid = l + ( r - l ) / 2 ; //如果刚好找到 if ( arr [

前序遍历、中序遍历和后序遍历

半腔热情 提交于 2020-02-04 06:52:19
前序遍历: 前序遍历就像是从根节点出发的一个小人围着树跑了一圈 中序遍历 中序遍历就像是树画好之后在底下的投影 比如这个图,中序遍历的结果就是HDIBEJAFKCG 后序遍历: 后续遍历就像剪葡萄,将葡萄一颗颗的剪下来 比如这个图:HIDJEBKFGCA 来源: CSDN 作者: minastinis of king 链接: https://blog.csdn.net/qq_40971025/article/details/104152382