Когда использовать стратегию обхода предварительного заказа, выполнения и пост-заказа
Прежде чем вы сможете понять, при каких обстоятельствах использовать предварительный заказ, порядок и пост-заказ для двоичного дерева, вы должны точно понять, как работает каждая стратегия обхода. Используйте в качестве примера следующее дерево.
Корень дерева - 7 , крайний левый узел - 0 , крайний правый узел - 10 .
Обход предварительного заказа :
Резюме: начинается с корня ( 7 ), заканчивается в самом правом узле ( 10 )
Последовательность обхода: 7, 1, 0, 3, 2, 5, 4, 6, 9, 8, 10
Обход по порядку :
Сводка: начинается в крайнем левом узле ( 0 ), заканчивается в крайнем правом узле ( 10 )
Последовательность обхода: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Пост-заказ :
Резюме: начинается с самого левого узла ( 0 ), заканчивается корнем ( 7 )
Последовательность обхода: 0, 2, 4, 6, 5, 3, 1, 8, 10, 9, 7
Когда использовать предварительный заказ, заказ или пост-заказ?
Стратегия обхода, которую выбирает программист, зависит от конкретных потребностей разрабатываемого алгоритма. Цель - скорость, поэтому выберите стратегию, которая позволит вам получить нужные вам узлы максимально быстро.
Если вы знаете, что вам нужно исследовать корни, прежде чем осматривать какие-либо листья, вы выбираете предварительный заказ, потому что вы встретите все корни раньше всех листьев.
Если вы знаете, что вам нужно исследовать все листья перед любыми узлами, вы выбираете пост-заказ, потому что вы не тратите время на проверку корней в поисках листьев.
Если вы знаете, что дереву присуща последовательность в узлах, и вы хотите сгладить дерево до исходной последовательности, тогда следует использовать обход по порядку . Дерево будет сплющено так же, как оно было создано. Обход предварительного или последующего заказа может не вернуть дерево в последовательность, которая использовалась для его создания.
Рекурсивные алгоритмы для предварительного заказа, выполнения и пост-заказа (C ++):
struct Node{
int data;
Node *left, *right;
};
void preOrderPrint(Node *root)
{
print(root->name); //record root
if (root->left != NULL) preOrderPrint(root->left); //traverse left if exists
if (root->right != NULL) preOrderPrint(root->right);//traverse right if exists
}
void inOrderPrint(Node *root)
{
if (root.left != NULL) inOrderPrint(root->left); //traverse left if exists
print(root->name); //record root
if (root.right != NULL) inOrderPrint(root->right); //traverse right if exists
}
void postOrderPrint(Node *root)
{
if (root->left != NULL) postOrderPrint(root->left); //traverse left if exists
if (root->right != NULL) postOrderPrint(root->right);//traverse right if exists
print(root->name); //record root
}