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

摘要

总结二叉树的遍历方法,包括广度优先遍历、深度优先遍历以及前序、中序、后序遍历。
然后给出各种方法的递归和非递归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
    评论
以下是Java中二叉树遍历代码: - 前序遍历(Preorder Traversal):先访问根节点,然后递归遍历左子树,最后递归遍历右子树。 ```java public void preorderTraversal(TreeNode root) { if (root == null) { return; } System.out.print(root.val + " "); preorderTraversal(root.left); preorderTraversal(root.right); } ``` - 中序遍历(Inorder Traversal):先递归遍历左子树,然后访问根节点,最后递归遍历右子树。 ```java public void inorderTraversal(TreeNode root) { if (root == null) { return; } inorderTraversal(root.left); System.out.print(root.val + " "); inorderTraversal(root.right); } ``` - 后序遍历(Postorder Traversal):先递归遍历左子树,然后递归遍历右子树,最后访问根节点。 ```java public void postorderTraversal(TreeNode root) { if (root == null) { return; } postorderTraversal(root.left); postorderTraversal(root.right); System.out.print(root.val + " "); } ``` - 层序遍历(Level Order Traversal):按照树的层级逐层访问节点。 ```java public void levelOrderTraversal(TreeNode root) { if (root == null) { return; } Queue<TreeNode> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode node = queue.poll(); System.out.print(node.val + " "); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } } ``` 以上是一些常见的二叉树遍历方法,根据需要选择合适的遍历方式进行使用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java 二叉树详解 + 实现代码](https://download.csdn.net/download/weixin_38685521/13742233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [用Java实现二叉树遍历](https://blog.csdn.net/m0_61630116/article/details/124877205)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值