数据结构与算法之树的遍历

简介: 树的 “前” “中” “后” 遍历//如果要再写一个树太费时间了,所以博主在这篇博客只给出核心代码并赋予GIF演示动画,望大家好好理解以对树的三种遍历方式有更为深刻的理解

树的 “前” “中” “后” 遍历

//如果要再写一个树太费时间了,所以博主在这篇博客只给出核心代码并赋予GIF演示动画,望大家好好理解以对树的三种遍历方式有更为深刻的理解

  因为递归调用函数是有开销的,而且递归的次数受堆栈大小的限制,所以本篇博客不会
介绍用递归的方式来遍历树.  而是使用 栈 来遍历树.
首先让我们来了解什么是栈?

栈是存放数据对象的一种特殊容器,栈中的元素始终遵循后进先出的顺序


前序遍历(博主上篇已经写过了,所以直接套用上篇的代码):

前序遍历的主要思想就是:

根节点最先入栈,最先出栈

右子节点先入栈后处理;

左子节点后入栈先处理.

  Btree tmp;
  SqStack stack;
  InitStack(stack);
  PushStack(stack, *root);  //根节点进栈
  while (!(IsEmpty(stack))) { //栈为空,所有节点均已处理 
    PopStack(stack, tmp);   //要遍历的节点  
    printf("- %d -", tmp.data);   //打印要便利的节点的值
    if (tmp.rchild != NULL) {
      PushStack(stack, *(tmp.rchild)); //右子节点先入栈,后处理  
    }
    if (tmp.lchild != NULL) {
      PushStack(stack, *(tmp.lchild)); //左子节点后入栈,接下来先 处理  
    }
  }

前序遍历演示

image.gif

void inOrder(BinTree *root)  //非递归中序遍历
{
     stack<BinTree*> s;
     BinTree *p=root;
     while(p!=NULL||!s.empty())
     {
         while(p!=NULL)
         {
             s.push(p);
             p=p->lchild;
         }
         if(!s.empty())
         {
             p=s.top();
             cout<<p->data<<"";
             s.pop();
             p=p->rchild;
         }
     }   
}

一开始我们 BinTree *p=root;这样就能执行我们的第一个while循环

当跳出第一个while()循环时,就代表我们的中序遍历已经结束了。


1.第二个while在p不为空时执行: 在while循环下,将根节点先入栈,左子节点后入栈,然后继续判断p是否为空再决定是否继续如果满足那么左子节点再继续入栈(因为根节点在最前面所以现在入栈的就只有左子节点了,不会存在根节点反复入栈的情况)。那么while循环完的时候,我们的节点p此时一定为NULL; 如果现在出栈的话我们一定能保证出战的元素使我们要出的第一个节点!!!


2.出栈以及后续操作 if 语句 : 在步骤1操作之后,根节点以及最左边的节点将会全部入栈。此时我们现在的p为NULL;这样我们是无法进行后续操作的,那么我们应该如何做呢???

其实很简单只需要让我们的 p 只想现在的栈顶元素,再将数据输出到控制台,再将这个元素在栈中出栈即可。因为左子节点以及用过了,所以现在我们就执行 p=p->rchile 那么此时又会存在两种情况

(1)存在右子节点------->即p不为空,那么又会进入到步骤1;知道变成第二种情况。

(2)不存在右子节点--------> 那么在执行操作2(即继续出栈,向上查找)


gif演示:

20191016222949963.gif


后序遍历:

void postOrder3(BinTree *root)     //非递归后序遍历
{
     stack<BinTree*> s;
     BinTree *cur;                      //当前结点
     BinTree *pre=NULL;                 //前一次访问的结点
     s.push(root);
     while(!s.empty())
     {
         cur=s.top();
         if((cur->lchild==NULL&&cur->rchild==NULL)||
           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
         {
             cout<<cur->data<<"";  //如果当前结点没有孩子结点或者孩子节点都已被访问过
             s.pop();
             pre=cur;
         }
         else
         {
             if(cur->rchild!=NULL)
                 s.push(cur->rchild);
             if(cur->lchild!=NULL)   
                 s.push(cur->lchild);
         }
     }   
} 


对于后序遍历的理解:

首先定义两个可以指向树的指针

cur :指向当前节点

pre 指向上一个节点


现将根节点入栈(这一个会实现根节点最后出栈)


如果打while都已经跳出来了的话那么就说明已经完成后序遍历(因为我们先把根节点压进了栈,所以第一次是不会跳出我们的大循环的)


cur=s.top();将cur指向我们的栈顶(随着栈顶元素不断出栈,cur的指向会不断更改)


if(…) //如果当前结点没有孩子结点或者孩子节点都已被访问过(第一次循环的时候是不会进入这条语句的所以不要纠结最 孩子节点都已被访问过这句话!!!)

cout 想控制台打印元素,然后出栈

pre =cur; 这样就能实现pre指向上一个结点的功能了(也许会有人问,现在不是 pre=cur他们应该是指向一个结点的啊!!! 为什么要说 cur是指向当前节点 pre 是指向上一个结点啊? 因为在if结束了之后 cur就会指向新的栈顶元素!!!)


else(即在if判断不成立时进入else语句!!) 即当前节点存在孩子节点或者孩子节点还未被访问完!!

这里的思想就类似于前序遍历的思想了,只是没有前序遍历的 右节点存在,右节点入栈之后,左节点存在,左节点入栈,接着先入栈的后处理,后入栈的先处理的思想马上出站,而是要在满足我们的if条件才会进行出栈


gif演示:

20191016224243193.gif


希望大家能通过本篇博客掌握 树的三中遍历方式.


谢谢观看。?


目录
相关文章
|
23天前
|
机器学习/深度学习 算法 搜索推荐
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
Machine Learning机器学习之决策树算法 Decision Tree(附Python代码)
|
23天前
|
算法
【算法与数据结构】二叉树(前中后)序遍历2
【算法与数据结构】二叉树(前中后)序遍历
|
1月前
|
机器学习/深度学习 算法 数据挖掘
请解释Python中的决策树算法以及如何使用Sklearn库实现它。
决策树是监督学习算法,常用于分类和回归问题。Python的Sklearn库提供了决策树实现。以下是一步步创建决策树模型的简要步骤:导入所需库,加载数据集(如鸢尾花数据集),划分数据集为训练集和测试集,创建`DecisionTreeClassifier`,训练模型,预测测试集结果,最后通过`accuracy_score`评估模型性能。示例代码展示了这一过程。
|
1月前
|
机器学习/深度学习 算法
随机森林算法是如何通过构建多个决策树并将它们的预测结果进行投票来做出最终的预测的?
【2月更文挑战第28天】【2月更文挑战第102篇】随机森林算法是如何通过构建多个决策树并将它们的预测结果进行投票来做出最终的预测的?
|
1天前
|
算法
数据结构与算法-AVL树入门
数据结构与算法-AVL树入门
5 0
|
1天前
|
算法
数据结构与算法-Trie树添加与搜索
数据结构与算法-Trie树添加与搜索
5 0
|
1天前
|
机器学习/深度学习 数据采集 算法
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
共享单车需求量数据用CART决策树、随机森林以及XGBOOST算法登记分类及影响因素分析
|
2天前
|
机器学习/深度学习 算法 数据挖掘
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
R语言逻辑回归、Naive Bayes贝叶斯、决策树、随机森林算法预测心脏病
|
9天前
|
机器学习/深度学习 算法 数据可视化
样条曲线、决策树、Adaboost、梯度提升(GBM)算法进行回归、分类和动态可视化
样条曲线、决策树、Adaboost、梯度提升(GBM)算法进行回归、分类和动态可视化
13 0
|
10天前
|
算法 DataX
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”
二叉树(中)+Leetcode每日一题——“数据结构与算法”“剑指Offer55-I. 二叉树的深度”“100.相同的树”“965.单值二叉树”