打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【数据结构与算法】 通俗易懂讲解 二叉树遍历

通俗易懂讲解 二叉搜索树(请戳我)一文中主要介绍了二叉搜索树的性质,本文将继续介绍二叉树的遍历


二叉搜索树的遍历

遍历即将树的所有结点访问且仅访问一次。按照根节点位置的不同主要分为前序遍历,中序遍历,后序遍历。注意,二叉搜索树和普通的二叉树其遍历是一模一样的,因此下文中,不区分是二叉搜索树还是二叉树。


前序遍历

对一颗二叉树的前序遍历操作如下:

  • 访问节点

  • 前序遍历左子树

  • 前序遍历右子树

例如下图中二叉树前序遍历节点访问顺序为3 1 2 5 4 6

根据前面所分析的前序遍历的操作步骤,不难看出很容易用递归的方法实现二叉树的前序访问:

//序遍历递归版本
void preOrder(struct node *root)
{
if(root != NULL) { cout root->data ' '; preOrder(root->left); preOrder(root->right); }
}

其实,还能以非递归的方式实现二叉树的前序遍历:由于在遍历完根节点后还要将其找回来以便遍历该根节点对应的右子树,因此可以考虑使用来存储访问过的根节点,代码实现如下:

//序遍历的非递归版本
void preOrder(struct node *root)
{ stackstruct node *> s; while (root != NULL || !s.empty()) { if (root != NULL) { //访问结点并入栈 cout root->data ' '; s.push(root); root = root->left; //访问左子树   } else { root = s.top(); //回溯至父亲结点   s.pop(); root = root->right; //访问右子树   } } cout endl;
}


中序遍历

对一颗二叉树的中序遍历操作如下:

  • 中序遍历左子树

  • 访问节点

  • 中序遍历右子树

例如下图中二叉树中序遍历节点访问顺序为1 2 3 4 5 6

如同前序遍历一样,也可以用递归或者非递归的方式实现,而且其思想也类似,只是访问的顺序不一样了,其两种实现方式如下:

//序遍历递归版本
void inOrder(struct node *root)
{
if(root != NULL) { inOrder(root->left); //和前序遍历相比,只是输出语句换了个位置唯一 cout root->data ' '; inOrder(root->right); }
}

//序遍历的非递归版本
void inOrder(struct node *root)
{ stackstruct node *> s; while (root != NULL || !s.empty()) { if (root != NULL) { s.push(root); root = root->left; } else { //访问完左子树后才访问根结点   root = s.top(); cout root->data ' '; s.pop(); root = root->right; //访问右子树   } } cout endl;
}


后续遍历

对一颗二叉树的后序遍历操作如下:

  • 后序遍历左子树

  • 后序遍历右子树

  • 访问节点

例如下图中二叉树后序遍历节点访问顺序为2 1 4 6 5 3

二叉树序遍历递归版本与前序中序类似,如下:

//序遍历递归版本
void postOrder(struct node *root)
{
if(tree != NULL) { postOrder(root->left); postOrder(root->right); //最后访问根节点 cout root->data ' '; }
}

后序遍历的非递归算法较复杂,使用一个栈可以实现,但是过程很繁琐,我们可以考虑用两个栈来实现后序遍历的非递归算法。注意到后序遍历可以看作是下面遍历的过程:即先遍历某个结点,然后遍历其右孩子,然后遍历其左孩子。这个过程逆过来就是后序遍历。算法步骤如下:

(1)   push根结点到第一个栈s中。

(2)  从栈s中pop一个结点,将其push到栈output中。

(3)  然后push结点的左孩子和右孩子到第一个栈s中。

(4)  重复过程2和3直到栈s为空。

(5)  现在所有结点已经push到栈output中,且按照后序遍历的顺序存放,直接全部 pop出来即是二叉树后序遍历结果。

代码实现如下:

//序遍历的非递归版本
void postOrder(struct node *root)
{ if (!root) return; stackstruct node*> s, output; s.push(root); while (!s.empty())
   { struct node *curr = s.top(); output.push(curr); s.pop(); if (curr->left) s.push(curr->left); if (curr->right) s.push(curr->right); } while (!output.empty())
   { cout output.top()->data ' '; output.pop(); } cout endl;
}


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
深入遍历二叉树的各种操作详解(非递归遍历)
二叉树系列(1)已知二叉树的中序遍历和前序遍历,如何求后序遍历
二叉树前序、中序、后序遍历相互求法
二叉树后序遍历(非递归)
二叉树先序、中序、后序遍历的非递归实现
【经典面试题二】二叉树的递归与非递归遍历(前序、中序、后序)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服