Ternary tree preoder traversal (recursive implementation)
Class Definition

First of all, I would separate the class definition from the actual use case. The challenge wants you to walk nodes with integer data, but a next challenge may ask you to use a string instead. Don't let the use case stipulate the class definition. Let's make a generic class to make the tree reusable for more scenarios.

public class TernaryTree&lt;T&gt;
{
    public T Data { get; set; }
    public TernaryTree&lt;T&gt; Left { get; set; }
    public TernaryTree&lt;T&gt; Right { get; set; }
    public TernaryTree&lt;T&gt; Middle { get; set; }
}


DRY Code

You then present a method PreOrderTraversal which combines walking the tree with outputting data for this use case. It's a pitty the flow is not split from the use case. We would have to rewrite that flow for every single use case like this. Let's keep it DRY.

We want to have a non specific flow for traversing the tree pre-order, middle, left, then right.

public IEnumerable&lt;TernaryTree&lt;T&gt;&gt; WalkPreOrder()
{
    yield return this;
    foreach (var descendant in Middle?.WalkPreOrder())
    {
        yield return descendant;
    }
    foreach (var descendant in Left?.WalkPreOrder())
    {
        yield return descendant;
    }
    foreach (var descendant in Right?.WalkPreOrder())
    {
        yield return descendant;
    }
}


Use Case

And now we can reuse that method for our use case. This code should not be part of TernaryTree but rather of our unit test, or container class for the challenge:

 static void Print(TernaryTree&lt;int&gt; tree)
 {
     foreach (var node in tree.WalkPreOrder())
     {
         Console.WriteLine(node.Data);
     }
 }


Unit Tests

I noticed a comment in your code // manually verify the console output is 1 2 22 3 33 4 5. You can avoid manually checking the outcome by writing unit tests.



What's Next?

Since you can set any node to any of the child positions, you might introduce cycles. Suppose you set node.Left = node, this would be a cycle because of a self-to-child reference. As a challenge, you should try to figure out how to prevent cycles.


public TernaryTree Left   { get; set; }
public TernaryTree Right  { get; set; }
public TernaryTree Middle { get; set; }