Возможно, уже слишком поздно, но я считаю, что здесь стоит указать. То, что вышеупомянутые ответы предлагают здесь, относится исключительно к сериализации двоичного (поискового) дерева. Представьте, что вы хотите восстановить дерево позже, учитывая его сериализованную версию. Вы должны разметить листья, чтобы при попытке перестроить дерево было ясно, какой узел является дочерним по отношению к другому. Для этого просто добавьте NULL-ссылки в массив (или список) при обнаружении конечного узла. Однако при переходе на один уровень вверх добавьте еще одну NULL-ссылку на массив. Другими словами, перед возвратом из каждой рекурсии просто добавьте NULL в массив, который был передан методу. Таким образом, любое движение на один уровень вверх приведет к вставке NULL в массив. При восстановлении списка добавляйте элементы в стек, когда вы читаете их из массива слева направо. Нажав на пустую ссылку, вы выталкиваете () самый верхний объект из стека и оставляете следующий peek () стека, чтобы указать на него как на одного из его дочерних элементов. Перейдите к следующему элементу в массиве и повторите ту же процедуру. Возможно, есть более эффективные способы дальнейшей оптимизации этого подхода, но это то, что я хотел упомянуть. Надеюсь, это поможет.