Итак, создайте массив структур, которые имеют номер родительского узла и высоту. Изначально все высоты будут равны 0, за исключением корня, высота которого вы установили равным 1. Учитывая ваш пример ввода, у вас есть:
[
{4, 0},
{-1, 1},
{4, 0},
{1, 0},
{1, 0}
}
Теперь, начиная с первого элемента в списке, найдите его родителя. Если высота родителя не равна нулю, то высота узла на единицу больше, чем высота родителя. В противном случае найдите родителя родителя и посмотрите, установлена ли его высота и т. Д.
Вы используете стек для отслеживания посещенных вами узлов.
Алгоритм выглядит примерно так:
for each index, n
while a[n].height == 0
stack.push(n)
n = a[n].parent
parent = n;
while !stack.isEmpty()
stack.pop(n)
a[n].height = a[parent].height + 1
parent = n
На данный момент все высоты узлов установлены. Вы можете отсканировать массив, чтобы найти максимальную высоту.
Очевидной оптимизацией является отслеживание максимальной высоты при сканировании дерева. То есть после очистки стека вы делаете это:
if (a[n].height > max_height)
max_height = a[n].height;
Учитывая ваш ввод, мы начинаем с узла 0. Его высота равна 0, поэтому вы помещаете 0 в стек и смотрите на узел 4. Его высота также равна 0, поэтому вы смотрите на узел 1. Его высота равна 1, поэтому Вы выталкиваете стек и назначаете узлу 4 значение высоты 2. Затем вы снова выталкиваете стек и назначаете узлу 0 высоту 3. В итоге вы получите:
[
{4, 3},
{-1, 1},
{4, 0},
{1, 0},
{1, 2}
}
Узел 1 уже имеет свою высоту. Узел 2 имеет высоту 0, поэтому вы нажимаете на него и смотрите на узел 4. Его высота равна 2, поэтому вы извлекаете стек и назначаете узлу 2 значение высоты 3.
Узел 3 имеет высоту 0, поэтому вы смотрите на его родителя, который имеет высоту 1. Таким образом, высота узла 3 равна 2. Наконец, вы смотрите на узел 4, высота которого уже установлена. Ваш результат:
[
{4, 3},
{-1, 1},
{4, 3},
{1, 2},
{1, 2}
}