c++二叉树遍历

目录

二叉树节点结构:

[1.1 前序遍历(Preorder Traversal):](#1.1 前序遍历(Preorder Traversal):)

递归实现(preorderRecursive函数):首先访问当前节点,然后递归遍历左子树,最后递归遍历右子树。这种遍历方式可以用于深度优先搜索。

非递归实现(preorderIterative函数):

[2中序遍历(Inorder Traversal):中序遍历的顺序是左子树 -> 根节点 -> 右子树。](#2中序遍历(Inorder Traversal):中序遍历的顺序是左子树 -> 根节点 -> 右子树。)

[3后序遍历(Postorder Traversal):后序遍历的顺序是左子树 -> 右子树 -> 根节点。](#3后序遍历(Postorder Traversal):后序遍历的顺序是左子树 -> 右子树 -> 根节点。)

[4层序遍历(Level Order Traversal):层序遍历按照从上到下、从左到右的顺序遍历每一层的节点。](#4层序遍历(Level Order Traversal):层序遍历按照从上到下、从左到右的顺序遍历每一层的节点。)

[5深度优先遍历(Depth-First Traversal):深度优先遍历是一种通用的遍历方式,可以根据需要选择前序、中序、后序遍历方式。](#5深度优先遍历(Depth-First Traversal):深度优先遍历是一种通用的遍历方式,可以根据需要选择前序、中序、后序遍历方式。)


以下是C++中二叉树前序、中序、后序遍历的递归和非递归实现,以及层序遍历和深度优先遍历的代码和讲解。

二叉树节点结构:

cpp 复制代码
struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

1.1 前序遍历(Preorder Traversal)

前序遍历的顺序是根节点 -> 左子树 -> 右子树。

递归实现preorderRecursive函数):首先访问当前节点,然后递归遍历左子树,最后递归遍历右子树。这种遍历方式可以用于深度优先搜索。

cpp 复制代码
void preorderRecursive(TreeNode* root) {
    if (root == NULL) return;
    cout << root->val << " ";
    preorderRecursive(root->left);
    preorderRecursive(root->right);
}

非递归实现preorderIterative函数):

  • 使用一个栈来模拟递归,首先将根节点入栈,然后循环直到栈为空。在循环内,将栈顶节点出栈并访问,然后将右子节点和左子节点(如果存在)依次入栈,以确保下一次出栈的是左子节点。这样可以按照根-左-右的顺序遍历树。
cpp 复制代码
void preorderIterative(TreeNode* root) {
    if (root == NULL) return;
    stack<TreeNode*> s;
    s.push(root);
    while (!s.empty()) {
        TreeNode* node = s.top();
        s.pop();
        cout << node->val << " ";
        if (node->right) s.push(node->right);
        if (node->left) s.push(node->left);
    }
}

2中序遍历(Inorder Traversal) :中序遍历的顺序是左子树 -> 根节点 -> 右子树。

  • 递归实现inorderRecursive函数):首先递归遍历左子树,然后访问当前节点,最后递归遍历右子树。中序遍历可以按照从小到大的顺序遍历二叉搜索树的所有节点。

    cpp 复制代码
    void inorderRecursive(TreeNode* root) {
        if (root == NULL) return;
        inorderRecursive(root->left);
        cout << root->val << " ";
        inorderRecursive(root->right);
    }
  • 非递归实现inorderIterative函数):使用一个栈来模拟递归,从根节点出发,每次将当前节点以及所有左子节点入栈,然后出栈并访问节点,再处理右子节点。这样可以按照左-根-右的顺序遍历树。

    cpp 复制代码
    void inorderIterative(TreeNode* root) {
        stack<TreeNode*> s;
        TreeNode* curr = root;
        while (curr || !s.empty()) {
            while (curr) {
                s.push(curr);
                curr = curr->left;
            }
            curr = s.top();
            s.pop();
            cout << curr->val << " ";
            curr = curr->right;
        }
    }

3后序遍历(Postorder Traversal) :后序遍历的顺序是左子树 -> 右子树 -> 根节点。

  • 递归实现postorderRecursive函数):首先递归遍历左子树,然后递归遍历右子树,最后访问当前节点。后序遍历通常用于内存管理和资源释放。

    cpp 复制代码
    void postorderRecursive(TreeNode* root) {
        if (root == NULL) return;
        postorderRecursive(root->left);
        postorderRecursive(root->right);
        cout << root->val << " ";
    }
  • 非递归实现postorderIterative函数):需要两个栈,一个用于遍历,另一个用于输出。首先将根节点入遍历栈,然后在循环中,出栈并压入输出栈,然后将左子节点和右子节点分别压入遍历栈。最后,从输出栈中依次出栈并访问节点,得到后序遍历的结果。

    cpp 复制代码
    void postorderIterative(TreeNode* root) {
        if (root == NULL) return;
        stack<TreeNode*> s;
        stack<TreeNode*> output;
        s.push(root);
        while (!s.empty()) {
            TreeNode* node = s.top();
            s.pop();
            output.push(node);
            if (node->left) s.push(node->left);
            if (node->right) s.push(node->right);
        }
        while (!output.empty()) {
            TreeNode* node = output.top();
            output.pop();
            cout << node->val << " ";
        }
    }

4层序遍历(Level Order Traversal) :层序遍历按照从上到下、从左到右的顺序遍历每一层的节点。

  • 使用队列来实现。从根节点开始,将节点入队列,然后在循环中出队列并访问节点,同时将其子节点入队列。这样可以按照树的层级顺序遍历。

    cpp 复制代码
    void levelOrder(TreeNode* root) {
        if (root == NULL) return;
        queue<TreeNode*> q;
        q.push(root);
        while (!q.empty()) {
            TreeNode* node = q.front();
            q.pop();
            cout << node->val << " ";
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
    }

5深度优先遍历(Depth-First Traversal):深度优先遍历是一种通用的遍历方式,可以根据需要选择前序、中序、后序遍历方式。

  • 深度优先遍历是一种通用的遍历方法,可以根据需要选择前序、中序、后序遍历方式。在示例中,使用前序遍历的方式进行深度优先遍历。深度优先遍历通过栈来实现,首先将根节点入栈,然后在循环中出栈并访问节点,同时将右子节点和左子节点(按照栈的特性,右子节点先入栈)依次入栈,以确保下一次出栈的是左子节点。

    cpp 复制代码
    void depthFirst(TreeNode* root) {
        if (root == NULL) return;
        stack<TreeNode*> s;
        s.push(root);
        while (!s.empty()) {
            TreeNode* node = s.top();
            s.pop();
            cout << node->val << " ";
            if (node->right) s.push(node->right);
            if (node->left) s.push(node->left);
        }
    }
相关推荐
m0_720245012 小时前
1543.统计好三元组(简单)
开发语言·算法
To_OC2 小时前
LC 560 和为 K 的子数组:前缀和配哈希表,这对组合我是真的服了
javascript·算法·程序员
hans汉斯3 小时前
《软件工程与应用》期刊推荐&10月版面征稿中
图像处理·人工智能·深度学习·算法·音视频·软件工程
叠层归一研究院3 小时前
AGI 系统(八):符号范畴嵌入函子 — SymCat ↪ C_M107 严格化
c语言·开发语言·人工智能·算法·transformer·agi
其美杰布-富贵-李4 小时前
08 进阶评估指标与算法特定指标
人工智能·算法
.道阻且长.5 小时前
5.LeetCode算法习题讲解--双指针--有效三角形的个数
算法·leetcode·职场和发展
我是海飞5 小时前
杰理JL703N SSD1306 OLED(128x64) 点阵屏移植说明
单片机·算法·嵌入式·音频·杰理
wabs6666 小时前
关于图论【最短路径之Bellman_ford 算法(单源有限最短路)|卡码网96.城市间货物运输III的思考】
数据结构·算法·图论·卡码网·bellman_ford·单源有限最短路
会周易的程序员7 小时前
aiDgePLC — IEC61131-3 ST PLC 虚拟机调试与运行环境
c++·物联网·虚拟机·st·工业协议·iec61131·梯形图
lsylalalala8 小时前
常见的排序算法1
数据结构·算法·排序算法