总结二叉树的遍历方法(广度优先遍历、深度优先遍历以及前序、中序、后序遍历)

摘要

总结二叉树的遍历方法,包括广度优先遍历、深度优先遍历以及前序、中序、后序遍历。
然后给出各种方法的递归和非递归C++代码实现。


二叉树的遍历方法(广度优先遍历、深度优先遍历以及前序、中序、后序遍历)

在这里插入图片描述
术语定义:

  • D(The current node) 表示当前结点
  • L(left child) 表示左孩子结点
  • R(right child) 表示右孩子结点
  • 深度优先搜索(DFS, Depth First Search)可分为前序遍历(Preorder traversal), 中序遍历(Inorder Traversal)后序遍历(Postorder Traversal)

对于上图所示二叉树,不同的遍历结果为如下:

  • 深度优先搜索(DFS, Depth First Search)通常指的是前序遍历(Preorder traversal)?:遍历顺序规则为【DLR | 即当前结点, 左孩子, 右孩子】| 遍历结果:ABDGHCEIF
  • 中序遍历(Inorder Traversal) | 遍历顺序规则为【LDR】| 遍历结果:GDHBAEICF
  • 后序遍历(Postorder Traversal) | 遍历顺序规则为【LRD】| 遍历结果:GHDBIEFCA
  • 广度优先搜索(BFS, Breadth First Search) (又叫层次遍历)| 遍历顺序为【从上到下按层遍历,每层从左到右遍历】 | 遍历结果:ABCDEFGHI

tips:记忆前、中、后序遍历的小技巧。在前、中、后序遍历都是先L后R,只是D的位置不同。D放在第一个为DLR,就是前序遍历;D放在中间为LDR,就是中序便利;D放在后面为LRD,就是后序便利。

二叉树常用的4种遍历方式,总结如下表(如果图片太小可以点击放大):

遍历方式前序遍历中序遍历后序遍历层次遍历
遍历规则DLR,即当前结点, 左孩子, 右孩子LDRLRD从上到下按层遍历,每层从左到右遍历
遍历结果ABDGHCEIFGDHBAEICFGHDBIEFCAABCDEFGHI
遍历示意图前序遍历中序遍历后序遍历层次遍历

其它遍历方法

在这里插入图片描述

  • 对称遍历(自己起的名字) | 遍历结果:A BC DG HM IL EF JK | 实现方式:其实是对A节点的左子树进行前序遍历【DLR】,对A节点的右子树进行【DRL】遍历。另外为了保证同时对称的遍历,一次要同时访问2个结点。例如 Leetcode 101. 对称二叉树 就需要这么访问。

TODO:各种方法的递归和非递归C++代码实现

各种遍历的代码实现。包括递归版本和非递归版本。做成模板方便刷题。
可能参考:
参考1

首先定义二叉树结构:

//Definition for a binary tree node.
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

根据输入的前序遍历数组,创建二叉树:
注意:这里虽然只是前序遍历,但是按照完全二叉树来构建,所以生成的二叉树是唯一的


// 根据输入的前序遍历数组,创建二叉树
volatile int index = 0;
void CreateBiTree(TreeNode *&p_root, vector<int> &v_preOrder ){
    if(index >= v_preOrder.size())
        return;
    //按先序输入二叉树中结点的值(一个字符),空格字符代表空树,
    int val = v_preOrder[index++];
    if('#' != val){
        p_root = new TreeNode(val);//产生新的子树
        CreateBiTree(p_root->left, v_preOrder);//递归创建左子树
        CreateBiTree(p_root->right, v_preOrder);//递归创建右子树
    }   
    else{
        p_root = nullptr;
    }
    
}//CreateTree

/* binary tree
    A
   / \
  B   C
   \   \
    D   E
   /   / \
  F   G   H
*/
int main()
{
    // generate binary tree.
    TreeNode *p_root = nullptr;
    // # denote nullptr
    vector<int> v_preOrder = {'A', 'B', '#', 'D', 'F', '#', '#', '#', 'C', '#', 'E', 'G', '#', '#', 'H', '#', '#'};
    CreateBiTree(p_root, v_preOrder);

    // preorder traversal
    PreOrderTraversal_recursive(p_root);
    cout << endl;


    return 0;
}

前序遍历

递归实现:

void PreOrderTraversal_recursive(TreeNode *p_root){
	if(nullptr == p_root)
		return;
	printf("%c", p_root->val); // current node
	PreOrderTraversal_recursive(p_root->left);
	PreOrderTraversal_recursive(p_root->right);
}

非递归实现:


中序遍历

递归实现:

void InOrderTraversal_recursive(TreeNode *p_root){
	if(nullptr == p_root)
		return;
	InOrderTraversal_recursive(p_root->left);
	printf("%c", p_root->val); // current node
	InOrderTraversal_recursive(p_root->right);
}

非递归实现:


后序遍历

递归实现:

void PostOrderTraversal_recursive(TreeNode *p_root){
	if(nullptr == p_root)
		return;
	PostOrderTraversal_recursive(p_root->left);
	PostOrderTraversal_recursive(p_root->right);
	printf("%c", p_root->val); // current node
}

非递归实现:


广度优先搜索(BFS, Breadth First Search)

广度优先搜索(BFS, Breadth First Search)又叫层次遍历
队列实现:

// BFS
#include <queue>
void BreadthFirstSearch(TreeNode *p_root){
    if(nullptr == p_root)
        return;
	queue<TreeNode*> traversal_order;
    traversal_order.push(p_root);
    while(!traversal_order.empty()){
        TreeNode *p_curr = traversal_order.front();
        traversal_order.pop();
	    printf("%c", p_curr->val); // current node
        if(nullptr != p_curr->left){
            traversal_order.push(p_curr->left);
        }
        if(nullptr != p_curr->right){
            traversal_order.push(p_curr->right);
        }
    }
}

相关/参考链接

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值