Un modo di pensare a questo problema è quello di utilizzare il fatto che un ordine simmetrico a piedi l'albero produrrà tutti gli elementi in modo ordinato. Se è possibile rilevare deviazioni dal modo ordinato durante questa passeggiata, si può provare a individuare i due elementi che sono nel posto sbagliato.
Vediamo come fare questo per un semplice array ordinato prima, quindi userà il nostro algoritmo per costruire qualcosa che funziona sugli alberi. Intuitivamente, se si parte con un array ordinato e poi scambiare due elementi (non uguali!), Noi finire con un numero di elementi nella matrice essendo fuori posto. Ad esempio, data la gamma
1 2 3 4 5
Se invertire 2 e 4, si finisce con questa matrice:
1 4 3 2 5
Come potremmo rilevare che il 2 e 4 sono stati scambiati qui? Ebbene, poiché 4 è il maggiore tra i due elementi e furono permutati verso il basso, esso dovrebbe essere maggiore di entrambi gli elementi intorno ad esso. Analogamente, poiché 2 furono permutati up, dovrebbe essere inferiore entrambi gli elementi intorno ad esso. Da questo, si potrebbe concludere che 2 e 4 sono stati scambiati.
Tuttavia, questo non sempre funziona correttamente. Ad esempio, supponiamo che ci scambiamo 1 e 4:
4 2 3 1 5
Qui, sia 2 e 1 sono più piccoli dei loro elementi adiacenti, ed entrambi 4 e 3 sono più grandi di loro. Da questo possiamo dire che due di questi quattro in qualche modo sono stati scambiati, ma non è chiaro quali dovremmo scambiare. Tuttavia, se prendiamo il più grande e il più piccolo di questi valori (rispettivamente 1 e 4,), si finisce per ottenere la coppia che è stato scambiato.
Più in generale, di trovare gli elementi che sono stati scambiati nella sequenza, si desidera trovare
- Il più grande massimo locale nella matrice.
- Il più piccolo minimo locale nella matrice.
Questi due elementi sono fuori luogo e devono essere scambiati.
Ora, pensiamo a come applicare questo per alberi. Dal momento che un ordine simmetrico a piedi l'albero produrrà la sequenza ordinata con i due elementi su ordine, una possibilità sarebbe quella di camminare l'albero, registrare la sequenza in ordine simmetrico degli elementi che abbiamo trovato, quindi utilizzando l'algoritmo di cui sopra. Ad esempio, si consideri il tuo BST originale:
20
/ \
15 30
/ \ / \
10 17 25 33
/ | / \ / \ | \
9 16 12 18 22 26 31 34
Se noi Linearizzare questo in un array, otteniamo
9 10 16 15 12 17 18 20 22 25 26 30 31 33 34
Si noti che è maggiore di 16 elementi circostanti e 12 è inferiore al suo. Questo ci dice subito che il 12 e 16 sono stati scambiati.
Un semplice algoritmo per risolvere questo problema, dunque, sarebbe quella di fare una passeggiata in ordine simmetrico dell'albero di linearizzare in una sequenza come un vectoro deque, quindi per eseguire la scansione quella sequenza per trovare il più grande massimo locale ed il minimo locale più piccolo. Questo sarebbe eseguito in O (n), utilizzando O (n) spazio. Un algoritmo efficiente dello spazio più difficile ma più sarebbe tenere traccia solamente di tre nodi alla volta - il nodo corrente, il suo predecessore, e il suo successore - che riduce l'utilizzo della memoria a O (1).
Spero che questo ti aiuti!