当前位置: 首页 > news >正文

数据结构与算法-二叉树的遍历

在这里插入图片描述
🌞 “少年没有乌托邦,心向远方自明朗!”


二叉树

  • 🎈1.二叉树的遍历
    • 🔭1.1先序遍历
    • 🔭1.2中序遍历
    • 🔭1.3后序遍历
    • 🔭1.4层次遍历
    • 🔭1.5二叉树遍历的递归算法
      • 📝1.5.1先序遍历
      • 📝1.5.2中序遍历
      • 📝1.5.3后序遍历
      • 📝1.5.4例题一
      • 📝1.5.5例题二
      • 📝1.5.6例题三
    • 🔭1.6二叉树遍历的非递归算法
    • 🔭1.7例题四

🎈1.二叉树的遍历

二叉树的遍历是按照一定次序访问二叉树中的所有结点,且每个结点仅被访问一次的过程。遍历线性结构是容易解决的,而二叉树的结构是非线性结构,需要寻找规律,使二叉树的结点排列在一个线性队列上,便于遍历。

由二叉树的递归定义知,二叉树有根结点、左子树和右子树3个基本单元组成。如果以L、D、R分别表示遍历左子树、遍历根结点和遍历右子树,则遍历整个二叉树有DLR、LDR、LRD、DRL、RDL、RLD六种遍历方案。若规定先左后右,则只有DLR、LDR、LRD三种遍历方案,分别称为先序遍历、中序遍历和后序遍历
在这里插入图片描述

🔭1.1先序遍历

🔎先序遍历二叉树的过程如下:

  1. 访问根结点
  2. 先序遍历左子树
  3. 先序遍历右子树

✅ 如下图所示二叉树的先序序列为:ABJDGCEHF
在这里插入图片描述

🔭1.2中序遍历

🔎中序遍历二叉树的过程如下:

  1. 中序遍历左子树
  2. 访问根结点
  3. 中序遍历右子树

✅ 如下图所示二叉树的中序序列为:JBGDAEHCF
在这里插入图片描述

🔭1.3后序遍历

🔎后序遍历二叉树的过程如下:

  1. 后序遍历左子树
  2. 后序遍历右子树
  3. 访问根结点

✅ 如下图所示二叉树的后序序列为:JGDBHEFCA
在这里插入图片描述

🔭1.4层次遍历

🔎二叉树非空(设二叉树的高度为h时),层次遍历二叉树的过程如下:

  1. 先访问根结点(第1层)
  2. 再从左向右访问每层结点

✅ 如下图所示二叉树的层次序列为:ABCJDEFGH
在这里插入图片描述

🔭1.5二叉树遍历的递归算法

📝1.5.1先序遍历

void BiTree::InTraverse(BitNode* t)
{//中序遍历递归函数if (t){cout << data;InTraverse(t->lchild);InTraverse(t->rchild);}
}
void BiTree::InTraverseBiTree()
{BitNode* p = bt;InTraverse(p);
}

📝1.5.2中序遍历

void BiTree::InTraverse(BitNode* t)
{//中序遍历递归函数if (t){InTraverse(t->lchild);cout << data;InTraverse(t->rchild);}
}
void BiTree::InTraverseBiTree()
{BitNode* p = bt;InTraverse(p);
}

📝1.5.3后序遍历

void BiTree::InTraverse(BitNode* t)
{//中序遍历递归函数if (t){InTraverse(t->lchild);InTraverse(t->rchild);cout << data;}
}
void BiTree::InTraverseBiTree()
{BitNode* p = bt;InTraverse(p);
}

📝1.5.4例题一

已知二叉树采用二叉链表存储结构存储,设计一个交换二叉树左右子树的递归算法。
在这里插入图片描述

void ChangeSubTree(BitNode*& t)
{BitNode* temp;if (t){temp = new BitNode;temp = t->lchild;t->lchild = t->rchild;t->rchild = temp;ChangeSubTree(t->lchild);ChangeSubTree(t->rchild);}
}

📝1.5.5例题二

已知二叉树采用二叉链表结构存储,请设计一个判断两棵二叉树是否相似的算法。若相似返回1,否则返回0.所谓两棵二叉树st相似是指st均为空的二叉树;或者st的根结点相似(值可以不同),且左右子树分别相似。
在这里插入图片描述

int Alike(BitNode* s, BitTree* t)
{if (s == NULL && t == NULL)return 1;else if (s == NULL || t == NULL)return 0;elsereturn Alike(s->lchild, t->lchild) && Alike(s->rchild, t->rchild);
}

📝1.5.6例题三

已知二叉树采用二叉链表存储结构存储,设计一个将二叉树s拷贝给t的递归算法。
在这里插入图片描述

void CopyBitree(BitNode* s, BitNode*& t)
{if (s == NULL)t = NULL;else{t = new BitNode;t->data = s->data;CopyBiTree(s->lchild, t->lchild);CopyBiTree(s->rchild, t->rchild);}
}

🔭1.6二叉树遍历的非递归算法

为了把递归过程改成一个非递归过程,需要利用一个工作栈,记录遍历时的回退路径。

🔎先序遍历的算法流程:

  1. 用指针p指向当前需要处理的结点
  2. 访问该结点,该结点入栈,并将p指向左孩子,循环处理左子树
  3. 当该结点无左孩子时,表示栈顶结点无左子树,栈顶结点退栈,并将p指向刚出栈结点的右孩子
  4. 对右子树进行相同处理
  5. 重复上述过程,直到栈为空为止
void PreTraverse(BitNode* t)
{BitNode* p = t;SqStack s;while (p || !s.EmptyStack()){if (p){//访问根结点,根结点指针入栈,遍历左子树cout << p->data;//访问结点s.Push(p);p = p->lchild;}else{//根结点退栈,遍历右子树s.Pop(p);p = p->rchild;}}
}

🔎中序遍历的算法流程:

  1. 用指针p指向当前需要处理的结点,p入栈
  2. 扫描该结点的左子树上的所有结点并将它们一一进栈
  3. 当该结点无左孩子时,表示栈顶结点无左子树,栈顶结点退栈,该问该结点,并将p指向刚出栈结点的右孩子
  4. 对右子树进行相同处理
  5. 重复上述过程,直到栈为空为止
void PreTraverse(BitNode* t)
{BitNode* p = t;SqStack s;while (p || !s.EmptyStack()){if (p){//根结点入栈,遍历左子树s.Push(p);p = p->lchild;}else{//根结点退栈,访问结点,遍历右子树s.Pop(p);cout << p->data;//访问结点p = p->rchild;}}
}

🔎后序遍历的算法流程:

  1. 用指针p指向当前需要处理的结点,并置标志位flag=0(表示第一次入栈),p入栈
  2. 扫描该结点的左子树上的所有结点并将它们一一进栈
  3. 当该结点无左孩子时,表示栈顶结点无左子树,栈顶结点退栈,并判断标志位的值,若flag=0,置flag=1(表示该结点第二次入栈),该问该结点,并将p指向刚出栈结点的右孩子,若flag=1,则访问该结点,置p = NULL.
  4. 对右子树进行相同处理
  5. 重复上述过程,直到栈为空为止
typedef struct 
{BitNode* pointer;int flag;
}BitNodeFlag;
void PostTraverse(BitNode* t)
{BitNodeFlag bf;BitNode* p = t;SqStack s;while (p || !s.EmptyStack()){if (p){bf.pointer = p;bf.flag = 0;s.Push(bf);p = p->lchild;}else{s.Pop(bf);if (bf.flag == 0){bf.uflag = 1;s.Push(bf);p = p->rchild;}else{cout << bf.pointer->data;p = NULL;}}}
}

🔎层次遍历的算法流程:

层次遍历访问完某一层的结点后,再按照它们的访问次序对各结点的左、右子树顺序访问。如此一层一层地访问,先访问的结点其左、右孩子也要先访问。层次遍历过程可以用队列来实现。

void LevelTraverse(BitNode* t)
{BitNode* p = t;LinkQueue q;//初始化建立空队列if (p)q.Enqueue(p);//根结点入队while (!q.EmptyQueue()){q.DeQueue(p);//出队cout << p->data;//访问结点if (p->lchild)q.EnQueue(p->lchild);//左子树根结点入队if (p->rchild)q.EnQueue(p->rchild);//右子树根结点入队}
}

🔭1.7例题四

已知二叉树采用二叉链表存储结构存储,设计一个计算二叉树叶子结点的非递归算法。

int CountBitLeaf(BitNode* t)
{SqStack s;BitNode* p = t;int count = 0;while (p != NULL || !s.EmptyStack()){while (p != NULL){s.Push(p);p = p->lchild;}if (!s.EmptyStack()){s.Pop(p);if (p->lchild == NULL && p->rchild == NULL)count++;p = p->rchild;}}return count;
}

好啦,关于二叉树的遍历的知识到这里就先结束啦,后期会继续更新学习数据结构与算法的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

相关文章:

数据结构与算法-二叉树的遍历

&#x1f31e; “少年没有乌托邦&#xff0c;心向远方自明朗&#xff01;” 二叉树 &#x1f388;1.二叉树的遍历&#x1f52d;1.1先序遍历&#x1f52d;1.2中序遍历&#x1f52d;1.3后序遍历&#x1f52d;1.4层次遍历&#x1f52d;1.5二叉树遍历的递归算法&#x1f4dd;1.5.1先…...

Qt之普通项目如何生成DLL(含源码+注释)

文章目录 一、示例图二、普通项目需要改造的内容三、源码&#xff08;创建了一个TestDLL的项目&#xff0c;更改内容主要在pro文件和maindow.h文件&#xff09;TestDLL.promainwindow.hmainwindow.cppmainwindow.ui 总结 一、示例图 使用不同的编译模式编译&#xff0c;会在对…...

Java注解及自定义注解

注解/元数据&#xff08;Annotation&#xff09;&#xff0c;是对代码级别的说明&#xff1b;在JDK1.5及以后版本引入的一个特性&#xff0c;与类、接口、枚举是在同一个层次。可以声明在包、类、字段、方法、局部变量、方法参数等的前面&#xff0c;用来对这些元素进行说明、注…...

ps2024滤镜插件Portraiture

Photoshop 是最常用到的综合性的设计工具&#xff0c;虽然PS一直在迭代升级&#xff0c;但是在细节功能上&#xff0c;PS总是无法完全满足全部所有的用户需求&#xff0c;今天coco玛奇朵推荐一个个截至目前最受欢迎的免费的PS插件&#xff0c;有了这些功能扩展的插件后PS如虎添…...

Vue 实战项目(智慧商城项目): 完整的订单购物管理功能 内涵资源代码 基于Vant组件库 Vuex态管理 基于企业级项目开发规范

鹏鹏老师的实战开发项目 文章目录 智慧商城项目01. 项目功能演示1.明确功能模块2.项目收获 02. 项目创建目录初始化vue-cli 建项目 03. 调整初始化目录结构1.删除文件2.修改文件3.新增目录 04. vant组件库及Vue周边的其他组件库05. 全部导入和按需导入的区别06. 全部导入07. 按…...

JVM——一些零散的概念(后续学习深入了再补充)

Native 凡是带了native关键字的&#xff0c;说明Java的作用范围的达不到了&#xff0c;需要调用底层C语言的库 调用native方法&#xff0c;会进入本地方法栈&#xff0c;调用本地接口(JNI) JNI的作用&#xff1a;扩展Java的使用&#xff0c;融合不同的编程语言为Java所用 它在内…...

OpenCV学习(三)——响应鼠标事件(获取点击点坐标和颜色,利用鼠标进行绘图)

响应鼠标事件 3. 响应鼠标事件3.1 获取鼠标点击的坐标3.2 获取鼠标点击像素点的颜色3.3 在鼠标点击的位置生成圆3.4 通过拖动鼠标来绘制填充矩形3.5 通过拖动鼠标绘制未填充矩形3.6 使用鼠标选点绘制多边形3.7 按住鼠标左键进行绘图 3. 响应鼠标事件 使用OpenCV读取图像&#…...

基于安卓android微信小程序的投票系统

项目介绍 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;投票系统小程序被用户普遍使用&#xff0c;为方便用户…...

没有上司的舞会

有了上一篇博客&#xff0c;没有看上一篇博客的可以看看上一篇博客&#xff0c;我们对没有上司的舞会这道题会有更好的理解~ 所以关键的思路就是确定对于每一个节点我们应该维护什么内容才是最合适的&#xff0c;这个题目和上一篇博客的最后一道题目很相似&#xff0c;我们思考…...

2.18每日一题(不直接给f(x)的定积分及变上限积分)

...

RHCE8 资料整理(四)

RHCE8 资料整理 第四篇 存储管理第13章 硬盘管理13.1 对磁盘进行分区13.2 交换分区&#xff08;swap分区&#xff09; 第14章 文件系统14.1 了解文件系统14.2 了解硬链接14.3 创建文件系统14.4 挂载文件系统14.5 设置永久挂载14.6 查找文件14.7 find的用法 第15章 逻辑卷管理15…...

目标跟踪ZoomTrack: Target-aware Non-uniform Resizing for Efficient Visual Tracking

论文作者&#xff1a;Yutong Kou,Jin Gao,Bing Li,Gang Wang,Weiming Hu,Yizheng Wang,Liang Li 作者单位&#xff1a;CASIA; University of Chinese Academy of Sciences; ShanghaiTech University; Beijing Institute of Basic Medical Sciences; People AI, Inc 论文链接&…...

Flink Data Sink

本专栏案例代码和数据集链接: https://download.csdn.net/download/shangjg03/88477960 1. Data Sinks 在使用 Flink 进行数据处理时,数据经 Data Source 流入,然后通过系列 Transformations 的转化,最终可以通过 Sink 将计算结果进行输出,Flink Data Sinks 就是用于定义…...

机器学习——正则化

正则化 在机器学习学习中往往不知道需要不知道选取的特征个数&#xff0c;假如特征个数选取过少&#xff0c;容易造成欠拟合&#xff0c;特征个数选取过多&#xff0c;则容易造成过拟合。由此为了保证模型能够很好的拟合样本&#xff0c;同时为了不要出现过拟合现象&#xff0…...

【c++】打家劫舍(动态规划)

打家劫舍 题目难度&#xff1a;高阶 时间限制&#xff1a;1000ms 内存限制&#xff1a;256mb 题目描述 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff…...

eslint提示 xxx should be listed in the project's dependencies

有时候手动安装了一个npm包A&#xff0c;npm包A里面包含了npm包B&#xff0c;这时候如果 import xxx from npm包B;eslint会报错&#xff0c;提示 npm包B 不在 package.json 里面 解决方法&#xff1a;在 eslintrc.js 增加配置 module.exports {rules: {import/no-extraneous-d…...

H3C LC-5120-52SC-HI配置管理IP

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、MGMT是什么&#xff1f;二、配置步骤1.连接ConsoleWindowsLinux1.配置minicom2.使用minicom 2.配置管理端口3.配置Web管理4.http其它配置项 总结 前言 最近…...

数据结构与算法之排序: 归并排序 (Javascript版)

排序 排序&#xff1a;把某个乱序的数组变成升序或降序的数组 (这里用数组来做举例) 归并排序 该排序属于 分治 策略将一个问题分解为两个问题来计算&#xff0c;计算完成之后&#xff0c;就会得到子任务的解&#xff0c;这些解不是最终问题的解&#xff0c;还需要merge起来…...

Java练习题2021-2

"某地大数据防疫平台记录了往来的所有防疫相关信息&#xff0c;包括 本地或外地人员、健康码颜色、接种疫苗情况、最近一次核酸结果、最近一次核酸检测时间等。 该地某区域对于进入人员的要求为&#xff1a; 如果是本地人员&#xff0c;需要绿码和疫苗完全接种方可进入&am…...

深度学习面试题目01

01 什么是神经网络&#xff1f;02 请解释前馈神经网络&#xff08;Feedforward Neural Network&#xff09;的工作原理。03 什么是激活函数&#xff0c;为什么它在神经网络中重要&#xff1f;04 请解释反向传播算法&#xff08;Backpropagation&#xff09;05 什么是过拟合&…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来

一、破局&#xff1a;PCB行业的时代之问 在数字经济蓬勃发展的浪潮中&#xff0c;PCB&#xff08;印制电路板&#xff09;作为 “电子产品之母”&#xff0c;其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透&#xff0c;PCB行业面临着前所未有的挑战与机遇。产品迭代…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

unix/linux,sudo,其发展历程详细时间线、由来、历史背景

sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...