二叉树的遍历-递归-非递归

Posted min2day

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树的遍历-递归-非递归相关的知识,希望对你有一定的参考价值。

技术分享图片

二叉树如上图所示。

一、递归遍历

#include <iostream>
#include <stack>
using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x): val(x), left(NULL), right(NULL) {}
};

// 先序遍历,递归
// [1] [2] [4] [5] [6] [7] [3]
void preorder1(TreeNode* root) {
    if(!root)   return;
    cout << [ << root->val << "] ";
    preorder1(root->left);
    preorder1(root->right);
}

// 中序遍历,递归
// [4] [2] [6] [5] [7] [1] [3]
void inorder1(TreeNode* root) {
    if(!root)   return;
    inorder1(root->left);
    cout << [ << root->val << "] ";
    inorder1(root->right);
}

// 后序遍历,递归
// [4] [6] [7] [5] [2] [3] [1]
void postorder1(TreeNode* root) {
    if(!root)   return;
    postorder1(root->left);
    postorder1(root->right);
    cout << [ << root->val << "] ";
}

 二、非递归遍历

要借助栈或队列

// 先序遍历,非递归
void preorder2(TreeNode* root) {
    if(!root)   return;
    stack<TreeNode*> s;
    s.push(root);
    while(!s.empty()) {
        TreeNode* node = s.top();
        cout << [ << node->val << "] ";
        s.pop();
        if(node->right)  s.push(node->right);
        if(node->left)  s.push(node->left);
    }
}

初始化把根节点压栈,访问根节点并弹出,然后依次将右节点、左节点入栈,直到栈为空。

// 先序遍历,非递归
void preorder3(TreeNode* root) {
   stack<TreeNode*> s;
    while(root != NULL || !s.empty()) {
        if(root != NULL) {
            s.push(root);
            cout << [ << root->val << "] ";
            root = root->left;
        }
        else {
            root = s.top();
            s.pop();
            root = root->right;
        }
    }
}

思路:回溯。访问根节点的左孩子,访问左孩子的左孩子,直到左孩子为空,这个过程中把所有访问过的节点压栈,当左孩子为空,pop该节点,访问该节点的右孩子。空间复杂度O(logN) 和树的深度有关。时间复杂度O(N),所有节点都访问了一遍。

以上是关于二叉树的遍历-递归-非递归的主要内容,如果未能解决你的问题,请参考以下文章

遍历二叉树的递归与非递归代码实现

九十五二叉树的递归和非递归的遍历算法模板

九十五二叉树的递归和非递归的遍历算法模板

二叉树的非递归遍历怎么写?

二叉树的前中后序递归和非递归遍历操作代码

C语言,如何用非递归方法输出二叉树的根到所有叶子路径?