Sortare cu un arbore binar
Sortarea folosind un arbore binar (sortare arbore binar, sortare arbore, sortare arbore, sortare folosind un arbore binar, ing. sortare arbore ) este un algoritm de sortare universal care constă în construirea unui arbore binar de căutare prin cheile unui tablou (listă), urmată de asamblarea tabloului rezultat prin parcurgerea nodurilor arborelui construit în ordinea necesară a cheilor. Această sortare este optimă atunci când se primesc date prin citire directă dintr -un flux (de exemplu, un fișier, socket sau consolă).
Algoritm
- Construcția unui arbore binar.
- Asamblarea tabloului rezultat prin parcurgerea nodurilor în ordinea cerută a tastelor.
Eficiență
Procedura de adăugare a unui obiect la un arbore binar are o complexitate algoritmică medie de ordinul . În consecință, pentru n obiecte, complexitatea va fi , care clasifică sortarea folosind un arbore binar ca un grup de „sortări rapide”. Cu toate acestea, complexitatea adăugării unui obiect la un arbore dezechilibrat poate fi la fel de mare ca , ceea ce poate duce la o complexitate generală de ordinul .
Când se extinde fizic o structură arborescentă în memorie, sunt necesare cel puțin celule de memorie suplimentare (fiecare nod trebuie să conțină referințe la un element al matricei originale, la elementul părinte, la frunza din stânga și din dreapta), cu toate acestea, există modalități de a reduce memoria suplimentară necesară.
Exemple de implementare
Într-o formă simplă de programare funcțională în Haskell , acest algoritm ar arăta astfel:
Arborele de date a = Frunza | Nodul ( Arborele a ) a ( Arborele a )
insert :: Ord a => a -> Tree a -> Tree a
insert x Leaf = Node Leaf x Leaf
insert x ( Nod t y t' ) | x <= y = Nod ( insert x t ) y t'
insert x ( Node t y t' ) | x > y = Nodul t y ( inserați x t' )
aplatiza :: Arborele a -> [ a ]
aplatiza Frunza = []
aplatiza ( Nodul t x t' ) = aplatiza t ++ [ x ] ++ aplatiza t'
treesort :: Ord a => [ a ] -> [ a ]
treesort = aplatiza . foldr insert Leaf
Implementare în C++14 :
#include <memorie>
#include <cassert>
#include <algoritm>
#include <vector>
#include <iostream>
folosind namespace std ;
// clasă reprezentând o
clasă de arbore binar BinaryTree
{
protejat :
// structura nodului arborelui
binar BinaryTreeNode
{
shared_ptr < BinaryTreeNode > stânga , dreapta ; // tasta int subarboresc stânga și dreapta ; // tasta };
shared_ptr < BinaryTreeNode > m_root ; // rădăcina copacului protejată :
// procedura recursivă de inserare a cheii
// cur_node - nodul curent al arborelui cu care este comparat nodul inserat // node_to_insert - nodul inserat void insert_recursive ( const shared_ptr < BinaryTreeNode >& cur_node , const shared_ptr < BinaryTreeNode >& insert node ) _to_
{
assert ( cur_node != nullptr );
// compara
bool insertIsLess = node_to_insert -> cheie < cur_node -> cheie ;
if ( insertIsLess )
{
// se inserează în subarborele din stânga
dacă ( cur_node -> stânga == nullptr )
cur_node -> stânga = nod_to_insert ;
altfel
insert_recursive ( cur_node -> stânga , nod_to_insert );
}
altfel
{
// se inserează în subarborele din dreapta
dacă ( cur_node -> dreapta == nullptr )
cur_node -> dreapta = nod_to_insert ;
altfel
insert_recursive ( cur_node -> dreapta , nod_to_insert );
}
}
public :
void insert ( tasta int )
{
shared_ptr < BinaryTreeNode > node_to_insert ( nou BinaryTreeNode );
nod_to_insert -> cheie = cheie ;
if ( m_root == nullptr )
{
m_root = nod_la_inserare ;
întoarcere ;
}
insert_recursive ( m_root , node_to_insert );
}
public :
typedef function < void ( tasta int ) > Vizitator ;
protejat :
// procedura de traversare a arborelui recursiv
// cur_node - nodul vizitat în prezent void visit_recursive ( const shared_ptr < BinaryTreeNode >& cur_node , const Visitor & visitor )
{
assert ( cur_node != nullptr );
// vizitați mai întâi subarborele din stânga
dacă ( cur_node -> stânga != nullptr )
visit_recursive ( cur_node -> stânga , vizitator );
// vizitează elementul
vizitator curent ( cur_node -> cheie );
// vizitați subarborele din dreapta
dacă ( cur_node -> dreapta != nullptr )
visit_recursive ( cur_node -> dreapta , vizitator );
}
public :
void visit ( const Vizitator & vizitator )
{
if ( m_root == nullptr )
întoarcere ;
visit_recursive ( m_root , vizitator );
}
};
int main ()
{
BinaryTree ; _
// adăugarea elementelor la vectorul arborelui < int > data_to_sort = { 10 , 2 , 7 , 3 , 14 , 7 , 32 };
pentru ( valoare int : date_to_sort )
{
copac . inserare ( valoare );
}
// tree traversal
tree . vizitează ([]( int cheie_vizitata )
{
cout << cheie_vizitata << " " ;
});
cout << endl ;
// rezultatul executiei: 2 3 7 7 10 14 32
return 0 ;
}
Un exemplu de creare a unui arbore binar și sortare în Java :
// Compilați și tastați java TreeSort
class Tree {
public Tree left ; // subarborele stânga și dreapta și cheia
public Tree right ;
cheie publică ; _
public Tree ( int k ) { // constructor cu cheie de inițializare a
cheii = k ;
}
/* insert (adăugarea unui nou subarbore (cheie))
compară cheia subarborelui de adăugat (K) cu cheia nodului rădăcină (X).
Dacă K>=X, adăugați recursiv un nou arbore la subarborele din dreapta.
Dacă K<X, adăugați recursiv un nou arbore în subarborele din stânga.
Dacă nu există un subarboresc, atunci introduceți un nou arbore în acest loc
*/
public void insert ( Arborele aArborele ) {
if ( Arborele . cheia < cheia )
if ( stânga != nul ) stânga . inserare ( aTree );
else left = aTree ;
else
if ( right != null ) right . inserare ( aTree );
else right = aTree ;
}
/* traversează
Parcurge recursiv subarborele din stânga.
Aplicați funcția f (print) la nodul rădăcină.
Traversați recursiv subarborele din dreapta.
*/
public void traverse ( TreeVisitor vizitator ) {
if ( left != null )
left . traversează ( vizitator );
vizitator . vizita ( aceasta );
dacă ( corect != nul )
corect . traversează ( vizitator );
}
}
interfață TreeVisitor {
public void visit ( Tree node );
};
clasa KeyPrinter implementează TreeVisitor {
public void visit ( Tree node ) {
System . afară . println ( " " + nod . cheie );
}
};
class TreeSort {
public static void main ( String args [] ) {
Tree myTree ;
myTree = Arborele nou ( 7 ); // creează un arbore (cu cheie) myTree . inserați ( Arbore nou ( 5 ) ); // atașați subarborele myTree . inserare ( Arbore nou ( 9 ) ); MyTree . traversează ( nouă KeyPrinter ()); } }
Vezi și