Один из способов думать об этой проблеме заключается в использовании того факта, что Симметричная прогулка дерева будет производить все элементы в отсортированном порядке. Если вы можете обнаружить отклонение от упорядоченных во время этой прогулки, вы можете попытаться найти два элемента, которые находятся в неправильном месте.
Давайте посмотрим, как это делается для простого отсортированного массива, а затем будет использовать наш алгоритм, чтобы построить что-то, что работает на деревьях. Наглядно, если мы начнем с отсортированным массивом, а затем поменять местами две (неравные!) Элементов, мы в конечном итоге с некоторым количеством элементов в массиве будучи неуместно. Например, если массив
1 2 3 4 5
Если поменять местами 2 и 4, мы в конечном итоге с этим массивом:
1 4 3 2 5
Как бы мы обнаружим, что 2 и 4 были заменены здесь? Ну, так как 4 является большей из двух элементов и был обменен вниз, оно должно быть больше, чем оба элемента вокруг него. Аналогичным образом, из-за 2 был обменен вверх, она должна быть меньше, чем оба из элементов вокруг него. Исходя из этого, можно сделать вывод, что 2 и 4 поменялись местами.
Однако, это не всегда работает правильно. Например, предположим, что мы переставляем 1 и 4:
4 2 3 1 5
Здесь, как и 1 2 меньше, чем их соседних элементов, и оба 4 и 3 больше, чем у них. Из этого мы можем сказать, что два из этих четырех как-то поменялись местами, но это не ясно, какие из них мы должны поменять местами. Однако, если взять самый большой и самый маленький из этих значений (1 и 4, соответственно), мы в конечном итоге получить пару, которая была выгружена.
В более общем плане, чтобы найти элементы, которые поменялись местами в последовательности, вы хотите найти
- Наибольший локальный максимум в массиве.
- Наименьший локальный минимум в массиве.
Эти два элемента из места и должны быть заменены.
Теперь давайте подумаем о том, как применить это к деревьям. Так как заказовМой прогулка дерева будет производить отсортированную последовательность с двумя элементами из заказа, один вариант был бы ходить по дереву, записи последовательности заказовМои элементов мы нашли, то, используя вышеупомянутый алгоритм. Например, рассмотрим исходный BST:
20
/ \
15 30
/ \ / \
10 17 25 33
/ | / \ / \ | \
9 16 12 18 22 26 31 34
Если линеаризуем это в массив, мы получаем
9 10 16 15 12 17 18 20 22 25 26 30 31 33 34
Обратите внимание на то, что 16 больше, чем окружающие ее элементы и что 12 меньше его. Это сразу говорит нам о том, что 12 и 16 были заменены.
Простой алгоритм для решения этой проблемы, поэтому, должен был бы сделать заказовМои прогулку дерева линеаризацию его в последовательность , как vectorО.Р. deque, затем отсканировать эту последовательность , чтобы найти самый большой локальный максимум и наименьший локальный минимум. Это будет работать в O (N) времени, используя O (N) пространства. Сложнее , но более пространственно-эффективный алгоритм будет держать только след трех узлов одновременно - текущий узел, его предшественник, и его преемник - что уменьшает использование памяти в O (1).
Надеюсь это поможет!