Swift Coding Test Course, Tree Traversal

Trees are one of the important data structures in computer science.
Having a deep understanding of trees can be advantageous when solving various problems.
In this lecture, we will explore the basic concepts of trees and how to traverse trees using Swift.
At the end, we will solve a problem that may appear in a real coding test.

1. Basic Concepts of Trees

A tree is a data structure composed of nodes.
Each node has a value and other nodes (child nodes) connected to it.
Trees have the following characteristics.

  • Root Node: The topmost node of the tree. (A node with no parent)
  • Leaf Node: A node that has no children.
  • Parent Node: A node that has children.
  • Subtree: A tree with its child node as the root.

2. Tree Traversal Methods

There are several ways to traverse a tree.
The most representative methods are Pre-order, In-order, and Post-order traversals.

2.1 Pre-order Traversal

  • Order: Node => Left Subtree => Right Subtree
  • Feature: The root node is visited first.

2.2 In-order Traversal

  • Order: Left Subtree => Node => Right Subtree
  • Feature: When traversing a binary search tree, values are output in ascending order.

2.3 Post-order Traversal

  • Order: Left Subtree => Right Subtree => Node
  • Feature: All child nodes are visited before visiting the parent node.

3. Coding Test Problem: Depth of a Binary Tree

Now we will implement a binary tree and apply each traversal method.
The given problem is to calculate the depth (maximum height) of a binary tree.

Problem Description

Write a function to find the maximum depth of the given binary tree, using the root node as the reference.
The depth is defined as the number of nodes in the longest path from the root node to a leaf node.

Example

Input: 
    1
   / \
  2   3
 / \
4   5

Output: 3 (Path from root 1 to 4 or 5)

3.1 Implementing the Binary Tree Node Class

First, we will implement a class (Node) to represent the nodes of a binary tree.

class Node {
    var value: Int
    var left: Node?
    var right: Node?

    init(value: Int) {
        self.value = value
        self.left = nil
        self.right = nil
    }
}

3.2 Implementing the Depth Calculation Function

The function to calculate the maximum depth of a binary tree can be structured as follows.

func maxDepth(_ root: Node?) -> Int {
    guard let node = root else { return 0 }

    let leftDepth = maxDepth(node.left)
    let rightDepth = maxDepth(node.right)

    return max(leftDepth, rightDepth) + 1
}

3.3 Complete Code

The complete code is as follows.

class Node {
    var value: Int
    var left: Node?
    var right: Node?

    init(value: Int) {
        self.value = value
        self.left = nil
        self.right = nil
    }
}

func maxDepth(_ root: Node?) -> Int {
    guard let node = root else { return 0 }

    let leftDepth = maxDepth(node.left)
    let rightDepth = maxDepth(node.right)

    return max(leftDepth, rightDepth) + 1
}

// Example tree creation
let root = Node(value: 1)
root.left = Node(value: 2)
root.right = Node(value: 3)
root.left?.left = Node(value: 4)
root.left?.right = Node(value: 5)

// Print maximum depth
let depth = maxDepth(root)
print("The maximum depth of the tree is: \(depth)")  // Output: The maximum depth of the tree is: 3

4. Reflections and Conclusion

In this lecture, we learned about the concepts of trees and how to traverse trees using Swift,
as well as how to calculate the depth of a tree through a coding test problem.
Since trees are utilized in various algorithms and data structures,
it is important to thoroughly understand and practice these fundamental concepts.
Implementing them in Swift while debugging and optimizing the code is also essential.
I hope you gain more experience by solving more algorithm problems in the future.