概述:

二叉树的遍历方式分为:
深度遍历(前序,中序,后序)
广度遍历(层次遍历)

二叉树是一种非常重要的数据结构,很多其它数据结构都是基于二叉树的基础演变而来的。对于二叉树,有深度遍历和广度遍历,深度遍历有前序、中序以及后序三种遍历方法,广度遍历即我们平常所说的层次遍历。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁,而对于广度遍历来说,需要其他数据结构的支撑,比如堆了。所以,对于一段代码来说,可读性有时候要比代码本身的效率要重要的多。

四种主要的遍历思想为:

前序遍历:根结点 ---> 左子树 ---> 右子树   (此处所谓的根节点是以当前点作为根节点,并不是指整个二叉树的根节点)

中序遍历:左子树---> 根结点 ---> 右子树     (此处所谓的根节点是以当前点作为根节点,并不是指整个二叉树的根节点)

后序遍历:左子树 ---> 右子树 ---> 根结点    (此处所谓的根节点是以当前点作为根节点,并不是指整个二叉树的根节点)

层次遍历:只需按层次遍历即可

例如,求下面二叉树的各种遍历

前序遍历:1  2  4  5  7  8  3  6

中序遍历:4  2  7  5  8  1  3  6

后序遍历:4  7  8  5  2  6  3  1

层次遍历:1  2  3  4  5  6  7  8

c++实现遍历方法:

BSTree.h

/*** C++ 语言: 二叉查找树** @author skywang* @date 2013/11/07*/#ifndef _BINARY_SEARCH_TREE_HPP_
#define _BINARY_SEARCH_TREE_HPP_#include <iomanip>
#include <iostream>
using namespace std;template <class T>
class BSTNode{public:T key;            // 关键字(键值)BSTNode *left;    // 左孩子BSTNode *right;    // 右孩子BSTNode *parent;// 父结点BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(),left(l),right(r) {}
};template <class T>
class BSTree {private:BSTNode<T> *mRoot;    // 根结点public:BSTree();~BSTree();// 前序遍历"二叉树"void preOrder();// 中序遍历"二叉树"void inOrder();// 后序遍历"二叉树"void postOrder();// (递归实现)查找"二叉树"中键值为key的节点BSTNode<T>* search(T key);// (非递归实现)查找"二叉树"中键值为key的节点BSTNode<T>* iterativeSearch(T key);// 查找最小结点:返回最小结点的键值。T minimum();// 查找最大结点:返回最大结点的键值。T maximum();// 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。BSTNode<T>* successor(BSTNode<T> *x);// 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。BSTNode<T>* predecessor(BSTNode<T> *x);// 将结点(key为节点键值)插入到二叉树中void insert(T key);// 删除结点(key为节点键值)void remove(T key);// 销毁二叉树void destroy();// 打印二叉树void print();private:// 前序遍历"二叉树"void preOrder(BSTNode<T>* tree) const;// 中序遍历"二叉树"void inOrder(BSTNode<T>* tree) const;// 后序遍历"二叉树"void postOrder(BSTNode<T>* tree) const;// (递归实现)查找"二叉树x"中键值为key的节点BSTNode<T>* search(BSTNode<T>* x, T key) const;// (非递归实现)查找"二叉树x"中键值为key的节点BSTNode<T>* iterativeSearch(BSTNode<T>* x, T key) const;// 查找最小结点:返回tree为根结点的二叉树的最小结点。BSTNode<T>* minimum(BSTNode<T>* tree);// 查找最大结点:返回tree为根结点的二叉树的最大结点。BSTNode<T>* maximum(BSTNode<T>* tree);// 将结点(z)插入到二叉树(tree)中void insert(BSTNode<T>* &tree, BSTNode<T>* z);// 删除二叉树(tree)中的结点(z),并返回被删除的结点BSTNode<T>* remove(BSTNode<T>* &tree, BSTNode<T> *z);// 销毁二叉树void destroy(BSTNode<T>* &tree);// 打印二叉树void print(BSTNode<T>* tree, T key, int direction);
};/** 构造函数*/
template <class T>
BSTree<T>::BSTree():mRoot(NULL)
{
}/** 析构函数*/
template <class T>
BSTree<T>::~BSTree()
{destroy();
}/** 前序遍历"二叉树"*/
template <class T>
void BSTree<T>::preOrder(BSTNode<T>* tree) const
{if(tree != NULL){cout<< tree->key << " " ;preOrder(tree->left);preOrder(tree->right);}
}template <class T>
void BSTree<T>::preOrder()
{preOrder(mRoot);
}/** 中序遍历"二叉树"*/
template <class T>
void BSTree<T>::inOrder(BSTNode<T>* tree) const
{if(tree != NULL){inOrder(tree->left);cout<< tree->key << " " ;inOrder(tree->right);}
}template <class T>
void BSTree<T>::inOrder()
{inOrder(mRoot);
}/** 后序遍历"二叉树"*/
template <class T>
void BSTree<T>::postOrder(BSTNode<T>* tree) const
{if(tree != NULL){postOrder(tree->left);postOrder(tree->right);cout<< tree->key << " " ;}
}template <class T>
void BSTree<T>::postOrder()
{postOrder(mRoot);
}/** (递归实现)查找"二叉树x"中键值为key的节点*/
template <class T>
BSTNode<T>* BSTree<T>::search(BSTNode<T>* x, T key) const
{if (x==NULL || x->key==key)return x;if (key < x->key)return search(x->left, key);elsereturn search(x->right, key);
}template <class T>
BSTNode<T>* BSTree<T>::search(T key)
{search(mRoot, key);
}/** (非递归实现)查找"二叉树x"中键值为key的节点*/
template <class T>
BSTNode<T>* BSTree<T>::iterativeSearch(BSTNode<T>* x, T key) const
{while ((x!=NULL) && (x->key!=key)){if (key < x->key)x = x->left;elsex = x->right;}return x;
}template <class T>
BSTNode<T>* BSTree<T>::iterativeSearch(T key)
{iterativeSearch(mRoot, key);
}/** 查找最小结点:返回tree为根结点的二叉树的最小结点。*/
template <class T>
BSTNode<T>* BSTree<T>::minimum(BSTNode<T>* tree)
{if (tree == NULL)return NULL;while(tree->left != NULL)tree = tree->left;return tree;
}template <class T>
T BSTree<T>::minimum()
{BSTNode<T> *p = minimum(mRoot);if (p != NULL)return p->key;return (T)NULL;
}/** 查找最大结点:返回tree为根结点的二叉树的最大结点。*/
template <class T>
BSTNode<T>* BSTree<T>::maximum(BSTNode<T>* tree)
{if (tree == NULL)return NULL;while(tree->right != NULL)tree = tree->right;return tree;
}template <class T>
T BSTree<T>::maximum()
{BSTNode<T> *p = maximum(mRoot);if (p != NULL)return p->key;return (T)NULL;
}/** 找结点(x)的后继结点。即,查找"二叉树中数据值大于该结点"的"最小结点"。*/
template <class T>
BSTNode<T>* BSTree<T>::successor(BSTNode<T> *x)
{// 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。if (x->right != NULL)return minimum(x->right);// 如果x没有右孩子。则x有以下两种可能:// (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。// (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。BSTNode<T>* y = x->parent;while ((y!=NULL) && (x==y->right)){x = y;y = y->parent;}return y;
}/** 找结点(x)的前驱结点。即,查找"二叉树中数据值小于该结点"的"最大结点"。*/
template <class T>
BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x)
{// 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。if (x->left != NULL)return maximum(x->left);// 如果x没有左孩子。则x有以下两种可能:// (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。// (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。BSTNode<T>* y = x->parent;while ((y!=NULL) && (x==y->left)){x = y;y = y->parent;}return y;
}/** 将结点插入到二叉树中** 参数说明:*     tree 二叉树的根结点*     z 插入的结点*/
template <class T>
void BSTree<T>::insert(BSTNode<T>* &tree, BSTNode<T>* z)
{BSTNode<T> *y = NULL;BSTNode<T> *x = tree;// 查找z的插入位置while (x != NULL){y = x;if (z->key < x->key)x = x->left;elsex = x->right;}z->parent = y;if (y==NULL)tree = z;else if (z->key < y->key)y->left = z;elsey->right = z;
}/** 将结点(key为节点键值)插入到二叉树中** 参数说明:*     tree 二叉树的根结点*     key 插入结点的键值*/
template <class T>
void BSTree<T>::insert(T key)
{BSTNode<T> *z=NULL;// 如果新建结点失败,则返回。if ((z=new BSTNode<T>(key,NULL,NULL,NULL)) == NULL)return ;insert(mRoot, z);
}/** 删除结点(z),并返回被删除的结点** 参数说明:*     tree 二叉树的根结点*     z 删除的结点*/
template <class T>
BSTNode<T>* BSTree<T>::remove(BSTNode<T>* &tree, BSTNode<T> *z)
{BSTNode<T> *x=NULL;BSTNode<T> *y=NULL;if ((z->left == NULL) || (z->right == NULL) )y = z;elsey = successor(z);if (y->left != NULL)x = y->left;elsex = y->right;if (x != NULL)x->parent = y->parent;if (y->parent == NULL)tree = x;else if (y == y->parent->left)y->parent->left = x;elsey->parent->right = x;if (y != z)z->key = y->key;return y;
}/** 删除结点(z),并返回被删除的结点** 参数说明:*     tree 二叉树的根结点*     z 删除的结点*/
template <class T>
void BSTree<T>::remove(T key)
{BSTNode<T> *z, *node;if ((z = search(mRoot, key)) != NULL)if ( (node = remove(mRoot, z)) != NULL)delete node;
}/** 销毁二叉树*/
template <class T>
void BSTree<T>::destroy(BSTNode<T>* &tree)
{if (tree==NULL)return ;if (tree->left != NULL)return destroy(tree->left);if (tree->right != NULL)return destroy(tree->right);delete tree;tree=NULL;
}template <class T>
void BSTree<T>::destroy()
{destroy(mRoot);
}/** 打印"二叉查找树"** key        -- 节点的键值* direction  --  0,表示该节点是根节点;*               -1,表示该节点是它的父结点的左孩子;*                1,表示该节点是它的父结点的右孩子。*/
template <class T>
void BSTree<T>::print(BSTNode<T>* tree, T key, int direction)
{if(tree != NULL){if(direction==0)    // tree是根节点cout << setw(2) << tree->key << " is root" << endl;else                // tree是分支节点cout << setw(2) << tree->key << " is " << setw(2) << key << "'s "  << setw(12) << (direction==1?"right child" : "left child") << endl;print(tree->left, tree->key, -1);print(tree->right,tree->key,  1);}
}template <class T>
void BSTree<T>::print()
{if (mRoot != NULL)print(mRoot, mRoot->key, 0);
}#endif

main.cpp

/*** C++ 语言: 二叉查找树** @author skywang* @date 2013/11/07*/#include <iostream>
#include "BSTree.h"
using namespace std;static int arr[]= {1,5,4,3,2,6};
#define TBL_SIZE(a) ( (sizeof(a)) / (sizeof(a[0])) )int main()
{int i, ilen;BSTree<int>* tree=new BSTree<int>();cout << "== 依次添加: ";ilen = TBL_SIZE(arr);for(i=0; i<ilen; i++){cout << arr[i] <<" ";tree->insert(arr[i]);}cout << "\n== 前序遍历: ";tree->preOrder();cout << "\n== 中序遍历: ";tree->inOrder();cout << "\n== 后序遍历: ";tree->postOrder();cout << endl;cout << "== 最小值: " << tree->minimum() << endl;cout << "== 最大值: " << tree->maximum() << endl;cout << "== 树的详细信息: " << endl;tree->print();cout << "\n== 删除根节点: " << arr[3];tree->remove(arr[3]);cout << "\n== 中序遍历: ";tree->inOrder();cout << endl;// 销毁二叉树tree->destroy();return 0;
}

参考文章:https://www.cnblogs.com/skywang12345/p/3576373.html

https://blog.csdn.net/My_Jobs/article/details/43451187

二叉树的遍历方法总结与c++实现相关推荐

  1. 重拾算法(3)——用458329个测试用例全面测试二叉树和线索二叉树的遍历算法

    重拾算法(3)--用458329个测试用例全面测试二叉树和线索二叉树的遍历算法 在"上一篇"和"上上一篇"中,我给出了二叉树和线索二叉树的遍历算法.给出算法容易 ...

  2. 算法(2)-二叉树的遍历(递归/迭代)python实现

    二叉树的遍历 1.深度优先DFS 1.1 DFS 递归解法 1.1.1先序遍历 1.1.2中序遍历 1.1.3后序遍历 1.2 DFS迭代解法 1.2.1先序遍历 1.2.2中序遍历 1.2.3后序遍 ...

  3. 算法与数据结构(三) 二叉树的遍历及其线索化(Swift版)

    前面两篇博客介绍了线性表的顺序存储与链式存储以及对应的操作,并且还聊了栈与队列的相关内容.本篇博客我们就继续聊数据结构的相关东西,并且所涉及的相关Demo依然使用面向对象语言Swift来表示.本篇博客 ...

  4. 《数据结构与算法》——树与二叉树之遍历总结

    <数据结构与算法>--树与二叉树之遍历总结 树与二叉树部分计划分为三次进行复习总结,第一次为基本概念和二叉树的遍历,第二次内容为线索二叉树以及树和森林,第三次为树与二叉树的应用. 目录 & ...

  5. 【数据结构复习】二叉树的遍历——从微软2014校园招聘说起

    [数据结构复习]是学习.复习常用数据结构系列文章.数据结构与算法密不可分,是程序实现功能的重要组成部分.优秀的数据结构可以提高算法的时间及空间效率.反之,将增加算法复杂度,甚至妨碍程序的正确执行. 一 ...

  6. 二叉树的遍历及解题思路

    文章目录 二叉树的遍历 一.深度优先遍历 1. 先序遍历 (1) 递归形式 (2) 非递归形式 2. 中序遍历 (1) 递归形式 (2) 非递归形式 3. 后序遍历 (1) 递归形式 (2) 非递归形 ...

  7. C++-二叉树递归遍历与非递归遍历实现

    -二叉树递归遍历与非递归遍历实现 引言 0 有关线性表结点定义-LinkNode 1 栈的链式存储结构实现-LinkedStack 2 队列的链式存储结构实现-LinkedQueue 3 二叉树的链式 ...

  8. c语言二叉树的遍历菜单系统,二叉树遍历C语言的实现

    广告 提供50多种云计算产品,包括云服务器和云. 创建一站式云产品试用服务,以帮助开发人员和企业以零门槛进入云环境. 上面的代码很简单,上面的图片很容易理解. 下一点是焦点: 二叉树的遍历分为前遍,中 ...

  9. 二叉树中序遍历方法实现

    对于二叉树的遍历,先序的方式是比较简单的,但是中序和后序的方式还是有点麻烦的,这里先给出一个用C++stack的遍历方式: 1.如果当前结点不为空把当前结点压入栈p=p->left转向其左孩子 ...

  10. 二叉树的六种遍历方法汇总(转)

    原文地址 ,两种思路都不错 第一种 前序 void preOrder(Node *p) //非递归 {if(!p) return;stack<Node*> s;Node *t;s.push ...

最新文章

  1. 【深度学习笔记】分类指标accuracy,recall,precision等的区别
  2. linux内核使用scons构建,如何使用scons进行交叉构建
  3. php mongodb连接数据库,PHP下 Mongodb 连接远程数据库的实例代码
  4. 4.android.mk编写规范
  5. 成立仅8个月的个人网站,月收入几十万美金
  6. jdk1.8_googleV3免费下载(API中文文档)
  7. python数据处理模块pandas_13. Python|模块总结:Pandas(数据处理)|【老W笔记】...
  8. Maven实战(Maven+Nexus建立私服【Linux系统】)
  9. 基于对抗生成网络的滚动轴承故障检测方法
  10. 鸿蒙手机发布失败,华为:没有推出鸿蒙手机计划,「自拍」会让人觉得你孤独和失败...
  11. 《面向对象分析与设计》一1.4面向对象方法的主要优点
  12. CSblog的学习记录
  13. 职场知识:什么是软件程序员?它是做什么的?
  14. Andromeda 源码解析 (同步获取服务)
  15. 用antd实现番茄钟
  16. 本周AI热点回顾:动森首届「AI 顶会」即将召开、《我的世界》里搭建神经网络、一位中国博士把整个CNN都给可视化了
  17. 微软Skype智能聊天机器人现登陆Mac平台和网页版
  18. php取FBOX数据,如何实现如下功能
  19. 第一课 大数据技术之Fink1.13的实战学习-部署使用和基础概念
  20. 年终盘点丨细数2017云栖社区20大热点话题(附100+话题清单)

热门文章

  1. 两个集合根据属性取差集_SQL高级知识——集合
  2. python3生成exe文件_python3.7打包成exe就三步
  3. 大多数微型计算机都是基于,基于PCI总线数据采集系统的设计
  4. mysql中文乱码过滤_记一次mysql中文字符乱码的问题排查
  5. antd vue 的table添加背景颜色_「教程」Spire.PDF教程:如何给PDF添加背景颜色和平铺背景图...
  6. Introduction to Computer Networking学习笔记(十五):End to End Delay 端对端延迟
  7. 《异度神剑2》与犹太教卡巴拉略考
  8. CocoStuff—基于Deeplab训练数据的标定工具【二、用已提供的标注数据跑通项目】...
  9. 面试总结——Java篇
  10. tensorflow函数介绍(3)