C++二叉树遍历总结\100. Same Tree

2023-11-09

转载请注明出处:http://blog.csdn.net/c602273091/article/details/55195284

理论学习

概念介绍

二叉树的遍历分成前序、中序、后序遍历。

前序就是访问结点的操作发生在遍历其左右子树之前。
中序就是访问结点的操作发生在遍历其左右子树之中,一般是遍历左边子树以后。
后序就是访问结点的操作发生在遍历其左右子树之后。

这里可以参考【1】中,对数据结构做了一个整理。

遍历图解

这里写图片描述
图中每个节点经过了3次。

先序为: A B D C E F
中序为: D B A E C F
后序为: D B E F C A

PS:(1) 在搜索路线中,若访问结点均是第一次经过结点时进行的,则是前序遍历;若访问结点均是在第二次(或第三次)经过结点时进行的,则是中序遍历(或后序遍历)。只要将搜索路线上所有在第一次、第二次和第三次经过的结点分别列表,即可分别得到该二叉树的前序序列、中序序列和后序序列。
  (2) 上述三种序列都是线性序列,有且仅有一个开始结点和一个终端结点,其余结点都有且仅有一个前趋结点和一个后继结点。为了区别于树形结构中前趋(即双亲)结点和后继(即孩子)结点的概念,对上述三种线性序列,要在某结点的前趋和后继之前冠以其遍历次序名称。上图所示的二叉树中结点C,其前序前趋结点是D,前序后继结点是E;中序前趋结点是E,中序后继结点是F;后序前趋结点是F,后序后继结点是A。但是就该树的逻辑结构而言,C的前趋结点是A,后继结点是E和F。

二叉树建立过程可以看:【2】

// 假设虚结点输入时以空格字符表示,相应的构造算法为:
void CreateBinTree (BinTree *T) { 
//构造二叉链表。T是指向根指针的指针,故修改*T就修改了实参(根指针)本身
    char ch;
    if((ch=getchar())=='') *T=NULL//读人空格,将相应指针置空 
    else{ //读人非空格
        *T=(BinTNode *)malloc(sizeof(BinTNode)); //生成结点
        (*T)->data=ch;
        CreateBinTree(&(*T)->lchild); //构造左子树
        CreateBinTree(&(*T)->rchild); //构造右子树
     }
}

遍历算法

1.中序遍历的递归算法定义:若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)访问根结点;
(3)遍历右子树。

2.先序遍历的递归算法定义:若二叉树非空,则依次执行如下操作:
(1) 访问根结点;
(2) 遍历左子树;
(3) 遍历右子树。

3.后序遍历得递归算法定义:若二叉树非空,则依次执行如下操作:
(1)遍历左子树;
(2)遍历右子树;
(3)访问根结点。

对于这个详细的图解,可以看【8】。

代码实践

参考【3】【4】中的代码建立二叉树。

实现模板

在【5】里,作者总结了一套很好的二叉树遍历的模板。以下为摘录部分。

前序遍历:

//前序遍历
void preorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        path.push_back(root->val);
        preorder(root->left, path);
        preorder(root->right, path);
    }
}

中序遍历:

//中序遍历
void inorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        inorder(root->left, path);
        path.push_back(root->val);
        inorder(root->right, path);
    }
}

后序遍历:

//后续遍历
void postorder(TreeNode *root, vector<int> &path)
{
    if(root != NULL)
    {
        postorder(root->left, path);
        postorder(root->right, path);
        path.push_back(root->val);
    }
}

非递归的前序:

//非递归前序遍历
void preorderTraversal(TreeNode *root, vector<int> &path)
{
    stack<TreeNode *> s;
    TreeNode *p = root;
    while(p != NULL || !s.empty())
    {
        while(p != NULL)
        {
            path.push_back(p->val);
            s.push(p);
            p = p->left;
        }
        if(!s.empty())
        {
            p = s.top();
            s.pop();
            p = p->right;
        }
    }
}

非递归的中序:

//非递归中序遍历
void inorderTraversal(TreeNode *root, vector<int> &path)
{
    stack<TreeNode *> s;
    TreeNode *p = root;
    while(p != NULL || !s.empty())
    {
        while(p != NULL)
        {
            s.push(p);
            p = p->left;
        }
        if(!s.empty())
        {
            p = s.top();
            path.push_back(p->val);
            s.pop();
            p = p->right;
        }
    }
}

非递归的后序:

//非递归后序遍历-迭代
void postorderTraversal(TreeNode *root, vector<int> &path)
{
    stack<TempNode *> s;
    TreeNode *p = root;
    TempNode *temp;
    while(p != NULL || !s.empty())
    {
        while(p != NULL) //沿左子树一直往下搜索,直至出现没有左子树的结点
        {
            TreeNode *tempNode = new TreeNode;
            tempNode->btnode = p;
            tempNode->isFirst = true;
            s.push(tempNode);
            p = p->left;
        }
        if(!s.empty())
        {
            temp = s.top();
            s.pop();
            if(temp->isFirst == true)   //表示是第一次出现在栈顶
            {
                temp->isFirst = false;
                s.push(temp);
                p = temp->btnode->right;
            }
            else  //第二次出现在栈顶
            {
                path.push_back(temp->btnode->val);
                p = NULL;
            }
        }
    }
}

在【5】中,作者提出了更加简单的二叉树实现,推荐看看。

在【6】中,作者提出了二叉树先中后序遍历(递归&非递归)算法、层次遍历(正序&逆序&锯齿形)非递归算法、二叉树深度算法、结点总数算法。

还有一些应用,比如搜索:二叉树的查找【7】

bintree search_tree(bintree t,datatype x){  
    if(!t){  
        return NULL;  
    }  
    if(t->data == x){  
        return t;  
    }else{  
        if(!search_tree(t->lchild,x)){  
            return search_tree(t->rchild,x);  
        }  
        return t;  
    }  
}  

统计节点的个数:

int count_tree(bintree t){  
    if(t){  
        return (count_tree(t->lchild)+count_tree(t->rchild)+1);  
    }  
    return 0;  
}  

比较两个数是否相同:

int is_equal(bintree t1,bintree t2){  
    if(!t1 && !t2){      //都为空就相等  
        return 1;  
    }  
    if(t1 && t2 && t1->data == t2->data){      //有一个为空或数据不同就不判断了  
        if(is_equal(t1->lchild,t2->lchild))  
            if(is_equal(t1->rchild,t2->rchild)){  
                return 1;  
            }  
    }  
    return 0;  
}

100. Same Tree

题目描述

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

代码实现

/**
 * 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 {
public:
    bool isSameTree(TreeNode* t1, TreeNode* t2) {
        if(!t1 && !t2){      //都为空就相等  
            return true;  
        }  
        if(t1 && t2 && t1->val == t2->val){      //有一个为空或数据不同就不判断了  
            if(isSameTree(t1->left,t2->left))  
                if(isSameTree(t1->right,t2->right)){  
                    return true;  
                }  
        }  
        return false;          
    }
};

【1】数据结构整理:http://student.zjzk.cn/course_ware/data_structure/web/shu/shu6.3.1.htm
【2】二叉树建立动画过程:http://student.zjzk.cn/course_ware/data_structure/web/flashhtml/erchashujianli.htm
【3】建立二叉树:http://blog.csdn.net/pony_maggie/article/details/38390513
【4】二叉树的三种遍历方法:http://blog.csdn.net/presidentpresident/article/details/7549170
【5】二叉树各种方法总结:http://www.jianshu.com/p/49c8cfd07410
【6】二叉树各种遍历方法:http://www.cnblogs.com/yfsmooth/p/4671903.html
【7】二叉树的很多应用:http://blog.csdn.net/fansongy/article/details/6798278/
【8】二叉树详细图解:http://www.cnblogs.com/yc_sunniwell/archive/2010/06/27/1766233.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++二叉树遍历总结\100. Same Tree 的相关文章

  • 如何将点光源转换为卵形/椭圆形?

    我希望通过具有不同 x 和 y 值的 vec2 半径将当前的圆形光变成椭圆形 有没有办法根据我当前在片段着色器中的代码来做到这一点 uniform struct Light vec4 colour vec3 position vec2 ra
  • 我可以在 WinRT / Windows 8 Store 应用程序中绑定 DynamicObject

    我有以下代码 public class MyClass DynamicObject INotifyPropertyChanged Dictionary
  • 当用户与 DateTimePicker 控件交互时会引发什么事件?

    我是 C 新手 在我的程序中使用 DateTimePicker Value Changed 事件 但我发现当用户单击箭头时发生 ValueChanged 事件 或者如果也以编程方式更改值 我只想识别 DateTimePicker 的用户交互
  • 如何从 OnChange 事件捕获文本框的值

    在我的 C MVC 应用程序中 我有一系列这样生成的文本框 foreach object item in items Html TextBox 渲染的结果是一系列看起来像这样的文本框
  • 将整数四舍五入到最接近的 10 倍数[重复]

    这个问题在这里已经有答案了 我想弄清楚如何对价格进行四舍五入 双向 例如 Round down 43 becomes 40 143 becomes 140 1433 becomes 1430 Round up 43 becomes 50 1
  • 从 proc/pid/cmdline 解析命令行参数

    我正在尝试解析命令行参数另一个程序 这是一个模拟器 在我的程序中使用system 命令和模拟器的pid 不幸的是同时使用文件读取和cat 输出格式不正确 所以我无法真正获取数据 cat在命令行上显示删除了空格的文件内容 整个字符串粘在一起
  • 如何从 UNC 中提取服务器名称

    谁能告诉我如何从 UNC 中提取服务器名称 ex 服务器名称 目录 目录 编辑 我很抱歉 但看起来我需要澄清一个错误 路径实际上更像是 服务器名 d 目录 我知道这可能会改变一些事情 怎么样Uri Uri uri new Uri serve
  • 如何测试 PARTIAL 视图在 C# ASP .NET MVC 中呈现

    我有一个视图 它内部有部分视图渲染 div class partialViewDiv Html RenderPartial partial Model SomeModelProperty div 和一个返回此视图的控制器 public Ac
  • FileStream - “不支持给定路径的格式”

    我正在尝试使用EPPlus http epplus codeplex com 在我们的 LAN 上保存电子表格 我正在使用一个FileStream对象执行此操作 但是每当我尝试实例化该对象时 我都会收到错误 The given path s
  • 使用正在运行的进程的共享内存收集核心转储

    核心转储仅收集进程空间 而不收集为进程间通信创建的共享内存 如何使核心转储也包含正在运行的进程的共享内存 设置核心文件过滤器 proc PID coredump filter per http man7 org linux man page
  • 在 QtCreator 中查看数组内容

    调试时是否可以在 Qt Creator 中查看数组的内容 似乎检测到我的数组是一个数组而不是一个指针 此外 我可以点击一个箭头 就像展开一样 但之后什么也没有显示 当我试穿的时候std vector Qt Creator 设法按预期显示内容
  • gcc总是做这种优化吗? (公共子表达式消除)

    作为示例 假设表达式sys gt pot atoms item gt P kind mass在循环内求值 循环只改变item 因此表达式可以简化为atoms item gt P kind mass通过将变量定义为atoms sys gt p
  • 串行端口轮询和数据处理

    我正在尝试通过微控制器从传感器的多个串行端口读取数据 每个串口将接收超过2000个测量值 每个测量值7个字节 全部为十六进制 而且他们同时开火 现在我正在从 4 个串行端口进行轮询 另外 我将每个测量值转换为字符串并将其附加到字符串构建器
  • 自定义编译器警告

    在 Net 中使用 ObsoleteAtribute 时 它 会向您发出编译器警告 告诉您该对象 方法 属性已过时 应使用其他内容 我目前正在从事一个需要大量重构前员工代码的项目 我想编写一个自定义属性 可用于标记方法或属性 这些方法或属性
  • C# - 使用 Linq 获取 Attribute 的属性

    我有一个属性 它本身就有属性 我想访问这些属性之一 布尔值 并检查它是否正确 我能够检查属性是否已设置 但这就是全部 至少对于 linq 来说是这样 属性 public class ImportParameter System Attrib
  • 带有 epgm 的 ZeroMQ PUB/SUB 无法接收同一主机上进程发送的消息

    我的所有进程都有两个套接字 一个 PUB 和一个 SUB 并且它们都使用相同的多播地址和端口 例如 PUB 会这样做 绑定 epgm 239 192 1 1 5555 SUB 将执行以下操作 连接 epgm 239 192 1 1 5555
  • 使用 std::set 时重载运算符<

    这是我第一次使用 std set 容器 并且我对操作符 std less 遇到了问题 我声明该集合 std set
  • 从原始 URL 获取重定向 URL

    我的数据库中有一个表 其中包含一些网站的 URL 我必须打开这些 URL 并验证这些页面上的一些链接 问题是某些 URL 被重定向到其他 URL 对于这样的 URL 我的逻辑是失败的 有什么方法可以传递原始 URL 字符串并获取重定向的 U
  • 通过 boost::python 将 C++ 对象传递给 python 函数

    我想在 C 应用程序中使用嵌入 python 并调用 python 脚本中定义的函数 该函数的参数是一个 C 对象 看我的代码 class Test public void f std cout lt lt sss lt
  • 如果 foreach 是一个结构数组,它会复制每个元素吗?

    我有一个结构数组 做foreach运算符在迭代数组时复制每个元素 据我所理解foreach只是底层的语法糖转换为for 所以看来答案是否定的 但我很想得到一些确认 PS 看来应该有人已经问过了 但我无法轻易找到任何东西 因此 请以提供的参考

随机推荐

  • OpenCV3 VideoCapture出错Connection to tcp://192.168.15.11:554?timeout=0 failed: No route

    tcp 0x2261180 Connection to tcp 192 168 15 11 554 timeout 0 failed No route to host joinus test 7689 GStreamer CRITICAL
  • Harbor主从

    一 harbor主从方案 1 主备 简单 主挂了切到备Harbor 同一时间只有一台提供服务 适合少量镜像下载 2 双主复制 双向配置复制 两台同时提供服务 前面增加负载均衡器 3 一主多从 多个从同步主 适合多地区业务 大量镜像下载需求
  • sqli-lab学习笔记(学习笔记)(21-30)

    打完21 30之后的后记 后来发现 网上所有就是讲解sqli的 到后面都没有用查有多少字段数的order by这个语句 几乎都没有提到过 我自己也尝试在后面的变形中加入加入进去但是不知道为什么老是出错 现在我想到的办法就是 比如28a关 语
  • 游戏开发Unity杂项知识系列:Microsoft Visual C++ 2015 安装失败 0x80070666-已安装这个产品的另一个版本

    参考 https blog csdn net qq 44781435 article details 108629616 总结 系统有了一个更高版本的vc 但是与所需不匹配 必须先卸载高版本的然后再安装目标版本
  • Python Selenium搭建UI自动化测试框架

    自动化测试是软件测试中非常重要的一部分 可以提高测试效率和测试覆盖率 在UI自动化测试中 Selenium是非常流行的工具 本文将介绍如何使用Python和Selenium搭建UI自动化测试框架 一 环境准备 在开始搭建UI自动化测试框架之
  • JavaScript资源大全中文版(Awesome最新版)

    Awesome系列的JavaScript资源整理 awesome javascript是sorrycc发起维护的 JS 资源列表 内容包括 包管理器 加载器 测试框架 运行器 QA MVC框架和库 模板引擎 数据可视化 时间轴 编辑器等 前
  • Elasticsearch安装IK分词器、配置自定义分词词库

    一 分词简介 1 单字分词 2 二分法分词 3 词库分词 二 配置IK中文分词器 三 配置自定义分词拓展词库 一 分词简介 在Elasticsearch中 假设搜索条件是 华为手机平板电脑 要求是只要满足了其中任意一个词语组合的数据都要查询
  • 自学软件测试6个月,找到了月薪8.5K的工作,多亏了这套学习方法

    8 5K的薪资也许对csdn的各位大佬来说并不算什么 但是对于我这种曾经在工厂 每月工资才4000左右的人来说 已经是巨大的改变了 文中附我的学习心得及学习资料 其实我在很早就对编程感兴趣 只是一直缺乏学习的动力 刚好在去年疫情期间 厂里停
  • vue + ts 项目中watch的用法

    要使vue支持ts写法 我们需要用到vue property decorator 这个组件完全依赖于vue class componet 首先安装 npm i D vue property decorator Watch path stri
  • Tkinter PhotoImage 踩坑记录

    1 直接使用PhotoImage file xxxx 报错 tkinter TclError couldn t recognize data in image file xxxxx png 原因 PhotoImage支持的图片格式有限 解决
  • MySQL视图、索引、备份与恢复、执行计划

    目录 一 前言 1 导读 2 学习的好处 二 视图 1 什么是视图 2 视图与数据表的区别 3 使用视图的优点 4 视图的语法 1 创建视图 CREATE VIEW 2 查询视图数据 3 更新视图数据 4 修改视图定义 ALTER VIEW
  • 超强实用:中国各地特产风味大搜捕!

    http www lotour com snapshot 2006 2 6 snapshot 32012 shtml 来源 中国交通旅游图册 北京特产风味 北京集全国风味佳肴 工艺美术和民族用品于一城 宫廷菜点 烤鸭 果脯 酥糖 京绣 戏装
  • 如何用Python让你的电脑说话

    如何用Python让你的电脑说话 你成为亿万花花公子的第一步 如果你是像 钢铁侠 这样的电影的粉丝 你可能已经幻想过得到你自己的贾维斯 那么 在这篇文章中 我将告诉你如何开始制作你自己的电脑助手 我们将通过一个小的编程和一些聪明的pytho
  • 图基本算法介绍:广度优先搜索、深度优先搜索、拓扑排序、强连通分支(算法篇)

    一 广度优先搜索 什么是广度优先搜索 在给定图G V E 后和一个特定的源顶点s的情况下 广度优先搜索 系统的探索G中的边 以期发现从s可以到达的所有顶点 并计算s到所有这些可达顶点之间的距离 即最少的边数 广度优先搜索的作用 个人从定义理
  • VC下加载多种格式图片的方法总结

    尽管VC有提供相应的API和类来操作bmp位图 图标和 增强 元文件 但却不支持jpg gif和png等格式的图片 而这几种格式却是常常要用到的 这里我给大家介绍两种办法来操作这些格式的图片 1 用API OleLoadPicture来加载
  • Object对象如何类获取对应类的属性值

    Object对象如何类获取对应类的属性值 public void test throws NoSuchFieldException IllegalAccessException Deposit deposit new Deposit dep
  • 卡方分布

    以上讲了一种称为服从正态分布的概率密度函数 今天 讲一讲服从 卡方分布 的概率密度函数 首先给出该函数的定义 自由度 是公式中一个重要参数 自由度不同 图形的形状也完全不同 众所周知 直线方程中的参数k是斜率 它控制着直线的倾斜角度 它不同
  • java中trim()方法

    string类型 指定要删除首部和尾部空格的字符串返回值String 函数执行成功时返回删除了string字符串首部和尾部空格的字符串 发生错误时返回空字符串 如果参数值为null时 会抛出空 指针异常 主要是为了防止复制过来首尾出现字符串
  • Day 15 - 面向对象2习题

    建立一个汽车类Auto 包括轮胎个数 汽车颜色 车身重量 速度等属性 并通过不同的构造方法创建实例 至少要求 汽车能够加速 减速 停车 再定义一个小汽车类CarAuto 继承Auto 并添加空调 CD属性 并且重新实现方法覆盖加速 减速的方
  • C++二叉树遍历总结\100. Same Tree

    理论学习 概念介绍 遍历图解 遍历算法 代码实践 实现模板 Same Tree 题目描述 代码实现 转载请注明出处 http blog csdn net c602273091 article details 55195284 理论学习 概念