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 le deviazioni dall'ordine ordinato durante questa passeggiata, è possibile provare a individuare i due elementi che si trovano nel posto sbagliato.
Vediamo come eseguire questa operazione per un array ordinato semplice, quindi utilizzeremo il nostro algoritmo per creare qualcosa che funzioni sugli alberi. Intuitivamente, se iniziamo con una matrice ordinata e poi scambiamo due elementi (non uguali!), Ci ritroveremo con un certo numero di elementi nell'array fuori posto. Ad esempio, dato l'array
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? Bene, poiché 4 è il maggiore dei due elementi ed è stato scambiato verso il basso, dovrebbe essere maggiore di entrambi gli elementi attorno ad esso. Allo stesso modo, poiché 2 è stato scambiato, dovrebbe essere più piccolo di entrambi gli elementi attorno ad esso. Da questo, potremmo concludere che 2 e 4 sono stati scambiati.
Tuttavia, questo non funziona sempre 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 vicini, ed entrambi 4 e 3 sono più grandi di loro.Da ciò possiamo dire che due di questi quattro sono stati scambiati in qualche modo, ma non è chiaro quali dovremmo scambiare. Tuttavia, se prendiamo il più grande e il più piccolo di questi valori (1 e 4, rispettivamente), finiamo per ottenere la coppia che è stata scambiata.
Più in generale, di trovare gli elementi che sono stati scambiati nella sequenza, si desidera trovare
- Il più grande massimo locale nella matrice.
- Il minimo locale minimo dell'array.
Questi due elementi sono fuori posto e devono essere scambiati.
Ora, pensiamo a come applicarlo agli alberi. Dal momento che una camminata interna dell'albero produrrà la sequenza ordinata con i due elementi fuori ordine, un'opzione sarebbe quella di camminare sull'albero, registrando la sequenza in ordine di 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 linearizzare questo in un array, otteniamo
9 10 16 15 12 17 18 20 22 25 26 30 31 33 34
Si noti che il 16 è maggiore rispetto ai suoi elementi circostanti e che il 12 è inferiore alla sua. Questo ci dice immediatamente che 12 e 16 sono stati scambiati.
un semplice algoritmo per risolvere questo problema, dunque, sarebbe quella di fare un ordine simmetrico a piedi l'albero di linearizzare in una sequenza come un vector
o deque
, quindi eseguire la scansione quella sequenza per trovare il più grande massimo locale e il più piccolo minimo locale. Questo sarebbe eseguito in tempo O (n), usando lo spazio O (n). Un algoritmo più complesso ma più efficiente in termini di spazio sarebbe tenere traccia di tre nodi alla volta, il nodo corrente, il suo predecessore e il suo successore, il che riduce l'utilizzo della memoria a O (1).
Spero che questo aiuti!
cosa fa getmax e getmin? non mi è chiaro cosa stai chiedendo. – phoxis
@phoxis: getMax e getMin trovano gli elementi max e min nella sottostruttura sinistra e destra della root principale. – Cipher
Vuoi dire: hai avuto un BST, due nodi sono stati scambiati "illegalmente" (quindi la tua struttura non è più un BST) e vuoi sapere quali? –