Я предполагаю, что рассмотрим только perfect BST. Потому что, если это не идеально, могут быть (возможно) несколько ответов.
Так что, глядя на примеры и описание preorder traversal, очевидно, что сначала берутся корни, а затем «вниз» к листьям. Поскольку у нас есть идеальное дерево, мы можем видеть, что листья всегда идут парами. А также нам нужно «пропустить» своих родителей.
Наглядно Я предложил бы идти в обратном направлении, а 2 последние элементы листья ('*' означает не листья):
< [*,*,2,4,*,7,9]
- The Overal процедура выглядит следующим образом (движение назад):
- взять 2 листа;
- пропустить 1 узел (их родительский элемент);
- повторные шаги [1-2];
- пропустить еще 1 узел (родитель родителей);
- сделано (осталось больше элементов).
Теперь демо на большом массиве (15 элементов, снова идеальное дерево)
[*,*,*,l,l,*,l,l,*,*,l,l,*,l,l]
< - где l
обозначает лист. Этапы (также назад):
- 1-4 из примера prevoius;
- еще раз 1-4 из предыдущего примера;
- пропустить еще 1 узел (родитель родителей родителей);
- сделано (не более элементов).
Надеюсь, у вас есть идея.
Что касается коммунистической программы подхода, вы можете обнаружить повторяющийся рисунок в выше интуитивном подходе и использовать рекурсию в зависимости от высоты дерева (можете быть easilly вычисляются как log2(n+1)
где n
является количеством элементов в дереве, также выглядит wiki) но, вероятно, начиная с начала массива.Псевдокод:
void getLeaves(int height) {
if (height == 2) { // there is only a parent and two childs (leaves)
skip(1); // skip 1 element
take(2); // next two are leaves, get them
}
else {
skip(1); // skip parent of parents (of parents ...)
getLeaves(height-1); // call on left part of array
getLeaves(height-1); // call on right part of array
}
}
Этот подход кажется правильным, хотя он основан на предположении, что дерево совершенное и полное, как предлагается в другом ответе. – loremIpsum1771
Я не думаю, что дерево должно быть совершенным или полным. Например: для [2,3] это не идеальное дерево, но для него работает алгоритм. –