Un mod de a gândi despre această problemă este de a utiliza faptul că o plimbare inordine a arborelui va produce toate elementele în ordine sortată. Dacă se poate detecta abateri de la comanda sortată în timpul acestei mers pe jos, puteți încerca să localizeze cele două elemente care sunt în locul greșit.
Să vedem cum se face acest lucru pentru o matrice de sortat simplu în primul rând, atunci va folosi algoritmul nostru pentru a construi ceva care funcționează pe copaci. Intuitiv, dacă vom începe cu o matrice de sortat și apoi schimba două elemente (non-egale!), Vom termina cu un numar de elemente din matrice fiind din loc. De exemplu, având în matrice
1 2 3 4 5
Dacă vom face schimb de 2 și 4, vom termina cu această matrice:
1 4 3 2 5
Cum detectăm că 2 și 4 au fost schimbate aici? Ei bine, din moment ce 4 este cea mai mare dintre cele două elemente și a fost schimbat în jos, ar trebui să fie mai mare decât atât a elementelor din jurul ei. În mod similar, pentru că 2 a fost schimbat în sus, ar trebui să fie mai mică decât atât a elementelor din jurul ei. Din aceasta, am putea concluziona că 2 și 4 au fost schimbate.
Cu toate acestea, acest lucru nu funcționează întotdeauna corect. De exemplu, să presupunem că vom schimba 1 și 4:
4 2 3 1 5
Aici, ambele 2 și 1 sunt mai mici decât elementele învecinate, iar ambele 4 și 3 sunt mai mari decât ale lor. Din aceasta putem spune că două dintre aceste patru într-un fel au fost schimbate, dar nu este clar care dintre ele ar trebui să interschimba. Cu toate acestea, dacă luăm cea mai mare și cea mai mică dintre aceste valori (1 și 4, respectiv), vom ajunge obtinerea perechea care a fost schimbat.
Mai general, pentru a găsi elementele care au fost schimbate în secvența, pe care doriți să găsiți
- Cel mai mare maxim local în matrice.
- Cel mai mic minim local în matrice.
Aceste două elemente sunt în afara de loc și ar trebui să fie schimbate.
Acum, să ne gândim cum să-l aplice la copaci. De la o plimbare inordine a arborelui va produce secvența de sortat cu cele două elemente din ordine, o opțiune ar fi să meargă copac, înregistrând secvența inordine a elementelor care le-am găsit, apoi folosind algoritmul de mai sus. De exemplu, ia în considerare BST original:
20
/ \
15 30
/ \ / \
10 17 25 33
/ | / \ / \ | \
9 16 12 18 22 26 31 34
Dacă ne linearize acest lucru într-o matrice, obținem
9 10 16 15 12 17 18 20 22 25 26 30 31 33 34
Observați că 16 este mai mare decât elementele sale înconjurătoare și că 12 este mai mică decât ei. Acest lucru ne spune imediat că 12 și 16 au fost schimbate.
Un algoritm simplu pentru rezolvarea acestei probleme, prin urmare, ar fi de a face o plimbare inordine de copac pentru a fi linearizat într - o secvență ca un vectorsau deque, apoi pentru a scana acea secvență pentru a găsi cea mai mare maxim local și cel mai mic minim local. Acest lucru ar fi în O (n), folosind O (n) spațiu. Un algoritm mai complicat , dar mult mai eficient din punct de spațiu ar fi să păstreze doar urmări trei noduri la un moment dat - nodul curent, predecesorul său, și succesorul său - care reduce utilizarea memoriei la O (1).
Sper că acest lucru vă ajută!