Развернуть бинарное дерево

Решение

Это первая задача на деревья, поэтому сперва определимся, что это за структура данных. Кстати, рассказать об этом интервьюеру, уточнив, что вы с ним понимаете о чем идёт речь одинаково, может быть не лишним.

Узлом назовём объект следующего вида:

function TreeNode(val) {
	this.val = val;
	this.left = this.right = null;
}

Каждый узел содержит две ссылки на другие узлы, которые условно называются дочерними. Т.к. их два — отсюда и «бинарное дерево» (по аналогии, существуют n-арные деревья, т.е. с n количеством дочерних узлов).

Итак, что же такое развернуть?

     4                   4
   /   \\               /   \\
  2     7    -->      7     2 
 / \\   / \\           / \\   / \\
1   3 6   9         9   6 3   1

Дерево будто отражается в зеркале: каждый левый узел становится правым.

Кстати, эта та самая задачка о которой писал Max Howell, автор Homebrew, которого не взяли в Google 😄

https://twitter.com/mxcl/status/608682016205344768

Решение становится понятным если попробовать развернуть дерево «руками», узел за узлом, и последить за тем, что мы делаем.

Представим сперва тривиальный случай:

     4                   4
   /   \\               /   \\
  2     7    -->      7     2 

Мы просто переставили левый и правый узел местами:

const tmp = root.left;
root.left = root.right;
root.right = tmp;

Исходное дерево после такой операции будет выглядеть так:

     4                   4
   /   \\               /   \\
  2     7    -->      7     2 
 / \\   / \\           / \\   / \\
**1   3 6   9         6   9 1   3**

Обратите внимание на последний ряд узлов — они не поменялись относительно своих родителей, потому что мы поменяли местами только непосредственных детей корня (4) и на этом остановились, а нужно сделать то же самое рекурсивно для их детей.

В любой рекурсии важно понимать о том, когда нужно остановиться, это называется базовый случай. В данном случае это когда узлы кончились, т.е. на вход получили null, ничего.