Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Binary Tree: Traversal Methods and Level Order Problems

Tech May 12 3

Binary Tree Terminology

  • Root Node: A node with no parent.
  • Leaf Node: A node with no children.
  • Edge: The line segment connecting two nodes.
  • Level: Incrementing from top to bottom, with the topmost level being 1.
  • Degree of a Node: The number of child nodes it has.
  • Height of a Binary Tree: The length (number of edges) from the root node to the farthest leaf node.
  • Depth of a Node: The length (number of edges) from the node to the root.
  • Height of a Node: The length (number of edges) from the node to the farhtest leaf node.

Preorder, Inorder, and Postorder Traversals (Recursive)

To determine the order: look at when the root node is visited.

  • Preorder: Root, Left, Right.
  • Inorder: Left, Root, Right (starts from the leftmost node).
  • Postorder: Left, Right, Root.
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    // Preorder traversal
    void traverse(TreeNode* node, vector<int>& result) {
        if (node == nullptr) return;
        result.push_back(node->val);
        traverse(node->left, result);
        traverse(node->right, result);
    }

    // Inorder traversal
    void traverseIn(TreeNode* node, vector<int>& result) {
        if (node == nullptr) return;
        traverseIn(node->left, result);
        result.push_back(node->val);
        traverseIn(node->right, result);
    }

    // Postorder traversal
    void traversePost(TreeNode* node, vector<int>& result) {
        if (node == nullptr) return;
        traversePost(node->left, result);
        traversePost(node->right, result);
        result.push_back(node->val);
    }

    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> result;
        traverse(root, result);
        return result;
    }
};

Level Order Traversal

Idea: Traverse the tree from top to bottom and left to right.

LeetCode 102: Binary Tree Level Order Traversal

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        vector<vector<int>> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            vector<int> currentLevel;
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                currentLevel.push_back(node->val);

                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            result.push_back(currentLevel);
        }
        return result;
    }
};

LeetCode 107: Binary Tree Level Order Traversal II

class Solution {
public:
    vector<vector<int>> levelOrderBottom(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        vector<vector<int>> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            vector<int> currentLevel;
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                currentLevel.push_back(node->val);
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            // The only difference from top-down: insert at the beginning
            result.insert(result.begin(), currentLevel);
        }
        return result;
    }
};

LeetCode 199: Binary Tree Right Side View

class Solution {
public:
    vector<int> rightSideView(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        vector<int> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            vector<int> currentLevel;
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                currentLevel.push_back(node->val);
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            // Only store the rightmost value of each level
            result.push_back(currentLevel.back());
        }
        return result;
    }
};

LeetCode 637: Average of Levels in Binary Tree

class Solution {
public:
    vector<double> averageOfLevels(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        vector<double> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            double sum = 0;
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                sum += node->val;
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            result.push_back(sum / levelSize);
        }
        return result;
    }
};

LeetCode 102: N-ary Tree Level Order Traversal

Note: The N-ary tree node uses a vector of children pointers instead of left and right.

/*
// Definition for a Node.
class Node {
public:
    int val;
    vector<Node*> children;

    Node() {}

    Node(int _val) {
        val = _val;
    }

    Node(int _val, vector<Node*> _children) {
        val = _val;
        children = _children;
    }
};
*/

class Solution {
public:
    vector<vector<int>> levelOrder(Node* root) {
        queue<Node*> q;
        q.push(root);
        vector<vector<int>> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            vector<int> currentLevel;
            for (int i = 0; i < levelSize; ++i) {
                Node* node = q.front();
                q.pop();
                currentLevel.push_back(node->val);
                for (auto child : node->children) {
                    if (child != nullptr) {
                        q.push(child);
                    }
                }
            }
            result.push_back(currentLevel);
        }
        return result;
    }
};

LeetCode 515: Find Largest Value in Each Tree Row

class Solution {
public:
    vector<int> largestValues(TreeNode* root) {
        queue<TreeNode*> q;
        q.push(root);
        vector<int> result;

        if (root == nullptr) return result;

        while (!q.empty()) {
            int levelSize = q.size();
            int maxVal = INT_MIN;
            for (int i = 0; i < levelSize; ++i) {
                TreeNode* node = q.front();
                q.pop();
                maxVal = max(maxVal, node->val);
                if (node->left != nullptr) {
                    q.push(node->left);
                }
                if (node->right != nullptr) {
                    q.push(node->right);
                }
            }
            result.push_back(maxVal);
        }
        return result;
    }
};
Tags: Binary Tree

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.