前序遍历

二叉树的链式实现

↘锁芯ラ 提交于 2019-12-21 07:21:22
相关术语: 平衡树,非平衡树,完全数,满树。 实现策略: 1)数组实现 这个还是非常重要的,有时间写一下,先用链来写 元素n的(从0开始按层编号)左子树编号为2n+1,右子树编号为2n+2,数学证明就略了,用这个来控制下标 2)模拟链式实现 3)链式实现 树是一种非线性结构,那么跟前不一样,必须根据你的需求 来构造新的节点才能满足树中的节点特征 : package Tree;public class BinaryTreeNode { protected Object element; protected BinaryTreeNode left,right; public BinaryTreeNode(Object element)//用元素来构造一个结点 { this.element = element; left = null; right = null; } public int numChildren(){//返回结点的子树上结点的个数 int count = 0; if(left != null) count = 1 + left.numChildren(); if(right != null) count = count + 1 + right.numChildren(); return count; } } 下面是一个实现了一些基本操作的二叉树的ADT

go语言浅析二叉树

自作多情 提交于 2019-12-19 04:47:26
Hello,各位小伙伴大家好,我是小栈君,今天给大家带来的分享是关于关于二叉树相关的知识点,并用go语言实现一个二叉树和对二叉树进行遍历。 我们主要针对二叉树的概念,go实战实现二叉树的前序遍历、中序遍历、后序遍历。 二叉树概念 在计算机科学领域内,二叉树代表的是具有两个节点的树形结构,通常子树被称作为“左子树”,右边的被称作为“右子树”。二叉树通常的应用于实现二叉查找树和二叉堆。 例如上述图片中,我们就制定了一个二叉树,其中d、e、f称作a树的叶子节点。 [叶子结点是离散数学中的概念。一棵树当中没有子结点(即度为0)的结点称为叶子结点,简称“叶子”。 叶子是指出度为0的结点,又称为终端结点] b和c 作为树a的孩子结点,b和a因为作为一个根a的孩子,所以他们的称呼为兄弟结点。其实总结一点就是关于二叉树各个结点的称呼其实和我们在家庭中,对于各个亲戚长辈的称呼类似。 在百度百科中也归纳除了关于二叉树的分类 一棵深度为k,且有2^k-1个结点的二叉树,称为满二叉树。这种树的特点是每一层上的结点数都是最大结点数。而在一棵二叉树中,除最后一层外,若其余层都是满的,并且或者最后一层是满的,或者是在右边缺少连续若干结点,则此二叉树为完全二叉树。 具有n个结点的完全二叉树的深度为floor(log2n) 1。深度为k的完全二叉树,至少有2k-1个叶子结点,至多有2k-1个结点。

非递归遍历二叉树(详解)

扶醉桌前 提交于 2019-12-19 03:19:05
本文转载自: http://blog.csdn.net/zhangxiangdavaid/article/details/37115355 前言   对于二叉树的递归遍历比较简单,所以本文主要讨论的是非递归版。其中,中序遍历的非递归写法最简单,后序遍历最难。    节点的定义: //Binary Tree Node typedef struct node { int data; struct node* lchild; //左孩子 struct node* rchild; //右孩子 }BTNode;   首先,有一点是明确的:非递归写法一定会用到栈,这个应该不用太多的解释。我们先看中序遍历: 中序遍历 分析   中序遍历的递归定义:先左子树,后根节点,再右子树。如何写非递归代码呢?一句话:让代码跟着思维走。我们的思维是什么?思维就是中序遍历的路径。假设,你面前有一棵二叉树,现要求你写出它的中序遍历序列。如果你对中序遍历理解透彻的话,你肯定先找到左子树的最下边的节点。那么下面的代码就是理所当然的: 中序代码段(i) BTNode* p = root; //p指向树根 stack <BTNode*> s; //STL中的栈 //一直遍历到左子树最下边,边遍历边保存根节点到栈中 while (p) { s.push(p); p = p->lchild; }  

数据结构---二叉树遍历

和自甴很熟 提交于 2019-12-18 22:27:55
二叉树遍历可以使用 深度优先遍历 和 广度优先遍历 ,深度优先又可以分为 前序、中序、后序 三种方式遍历,每种方式都可以通过递归和非递归方法实现。 一、深度优先递归遍历: 前序遍历算法: 先遍历根结点 再递归遍历左子树 最后递归遍历右子树 首先访问根结点A; 遍历A结点的左子树,B结点。 B结点有子结点,再按照前序遍历方式遍历,先访问根结点,即B; 遍历B结点左子树,D结点; D结点没有子结点,遍历B结点的右子树,E结点;到此,B结点的根结点、左子树、右子树、已经遍历完成; 遍历A结点的右子树,C结点; C结点有子结点,再按照前序遍历方式遍历,先访问根结点,即C; 遍历C结点左子树,F结点; F结点没有子结点,遍历C结点的右子树,G结点;到此,C结点的根结点、左子树、右子树、已经遍历完成; 最终的访问顺序为:A->B->D->E->C->F->G 代码实现: 结点类: //结点 public class TreeNode { private String data ; private TreeNode left ; private TreeNode right ; public TreeNode ( String data , TreeNode left , TreeNode right ) { this . data = data ; this . left = left ;

二叉树的前序、中序、后序遍历(递归、非递归)实现

寵の児 提交于 2019-12-17 08:37:21
本文部分来源于CSDN 兰亭风雨 大牛的原创。链接为 http://blog.csdn.net/ns_code/article/details/12977901 因为感觉大牛讲的很好,所以这里的文字讲解采用大牛的,大家可以直接看原创!代码部分是我自己的,leetcode代码,可在leetcode Accepted 二叉树是一种非常重要的数据结构,很多其他数据机构都是基于二叉树的基础演变过来的。二叉树有前、中、后三种遍历方式,因为树的本身就是用递归定义的,因此采用递归的方法实现三种遍历,不仅代码简洁且容易理解,但其开销也比较大,而若采用非递归方法实现三种遍历,则要用栈来模拟实现(递归也是用栈实现的)。下面先简要介绍三种遍历方式的递归实现,再详细介绍三种遍历方式的非递归实现 一、三种遍历方式的递归实现(比较简单,这里不详细讲解) 1、先序遍历——按照“根节点-左孩子-右孩子”的顺序进行访问 1 /** 2 * Definition for binary tree 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 {

数据结构之树

时光怂恿深爱的人放手 提交于 2019-12-14 07:26:28
数据结构之树(含代码) 树的基本概念 子树的个数没有限制,但它们一定是互不相交的 树的结点包含一个数据元素及若干指向其子树的分支;结点拥有的子树数称为结点的度;度为0的结点称为叶结点或终端结点;度不为0的结点称为非终端结点或分支结点;除根结点之外,分支结点也称为内部结点;树的度是树内各结点的度的最大值。 结点的层次从根开始定义起;树中结点的最大层次称为树的深度或高度; 如果将树中结点的各子树看成从左至右是有次序的,不能互换的,则称该树为有序树,否则称为无序树 双亲表示法 每个结点都有data和left,right,data是数据,存储结点的数据信息;而lef,rig是指针,存储该结点的双亲在数组中的下标;根结点没有双亲,所以指针域为-1; 二叉树 二叉树是n个结点的有限集合,该集合或者为空集,或者由一个根结点和两棵互不相交的、分别成为根结点的左子树和右子树的二叉树组成 二叉树的特点: 每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点 左子树和右子树是有顺序的,次序不能任意颠倒 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树 满二叉树:在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上 特点: 叶子只能出现在最下一层 非叶子结点的度一定是2 在同样深度的二叉树中,满二叉树的结点个数最多,子树最多 完全二叉树

二叉树的遍历

醉酒当歌 提交于 2019-12-14 05:43:16
1.前序遍历 1.递归 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { vector < int > re ; public : vector < int > preorderTraversal ( TreeNode * root ) { if ( root ) { re . push_back ( root - > val ) ; preorderTraversal ( root - > left ) ; preorderTraversal ( root - > right ) ; } return re ; } } ; 2.迭代 (1) 1.根节点入栈,出栈。 2.右子树先入栈,然后左子树入栈。 3.栈顶元素出栈 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode

线索二叉树 C++

最后都变了- 提交于 2019-12-13 13:01:59
线索二叉树 C++ 以此二叉树为例进行创建: 前序法创建节点,输入’#'表示为NULL 用前序创建的话需要输入 :ABD##E##C#G## 前序遍历:ABD##E##C#G## 中序遍历:#D#B#E#A#C#G# 后序遍历: ##D##EB###GCA 层序遍历: ABCDEG 在进行线索二叉树线索化的过程中我们并不设置 头结点, 而是**直接设置一个全局变量 指针 Prev **, 表示指向上一个节点的位置 。 思想: 1.首先对创建好的二叉树利用一次中序遍历的过程设置好 lTag 与 rtag 。 在这个过程中 T指针负责设置 T->ltag(前驱), prev指针负责设置 prev->rtag(后继) 2.中序线索二叉树的遍历 ,由于设置了前驱和后继,就可以不使用栈, 直接用 迭代法 进行中序遍历。 ThreadBiTree.h # pragma once # include <iostream> using namespace std ; # define MAX 30 typedef char ElemType ; typedef struct ThreadBiNode { ElemType data ; struct ThreadBiNode * lchild , * rchild ; int ltag , rtag ; //0表示正常连接孩子, 1表示前缀后缀

简单易懂带你了解二叉树

巧了我就是萌 提交于 2019-12-12 19:31:37
前言 上一篇博客为大家介绍了 数组与链表 这两种数据结构,虽然它们在某些方面有着自己的一些优点,但是也存在着一些自身的缺陷,本篇博客为将为大家介绍一下数据结构--- 二叉树 ,它在保留数组和链表的优点的同时也改善了它们的缺点(当然它也有着自己的缺点,同时它的实现也比较复杂). 1. 数组和链表的特点 数组的优点: 简单易用. 无序数组的插入速度很快,效率为O(1) 有序数组的查找速度较快(较无序数组),效率为O(logN) 数组的缺点: 数组的查找、删除很慢 数组一旦确定长度,无法改变 链表的优点: 可以无限扩容(只要内存够大) 在链表头的新增、删除很快,效率为O(1) 链表的缺点: 查找很慢 在非链表头的位置新增、删除很慢,效率为O(N) 2.树和二叉树 树是一种数据结构,因为它数据的保存形式很像一个树,所以得名为树(树状图). 而二叉树是一种特殊的树, 它的每个节点最多含有两个子树 ,现实世界中的二叉树: 图1 但是实际中的二叉树却是 倒挂 的,如图: 图2 二叉树的名词解释: 根:树顶端的节点称为根。一棵树只有一个根,如果要把一个节点和边的集合称为树,那么从根到其他任何一个节点都必须有且只有一条路径。A是根节点。 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点;B是D的父节点。 子节点:一个节点含有的子树的根节点称为该节点的子节点;D是B的子节点。 兄弟节点

二叉树非递归遍历

血红的双手。 提交于 2019-12-11 19:30:18
上码: 1 #include <iostream> 2 #include <string> 3 #include <stack> 4 #include <queue> 5 using namespace std; 6 7 template<class T> 8 struct BiNode { 9 T data; 10 BiNode<T> *lchild, *rchild;//左子树、右子树 11 }; 12 13 template<class T> 14 class BiTree 15 { 16 public: 17 BiTree(); //构造函数,初始化二叉树,前序序列由键盘输入 18 ~BiTree(); //析构函数,释放二叉链表中的各结点的存储空间 19 BiNode<T>* Getroot(); //获得指向根节点的指针 20 void PreOrder(BiNode<T>* root); //前序遍历二叉树 21 void InOrder(BiNode<T>* root); //中序遍历二叉树 22 void PostOrder(BiNode<T>* root); //后序遍历二叉树 23 void LeverOrder(BiNode<T>* root); //层序遍历二叉树 24 25 void NonPreOrder(BiNode<T>* root); 26