Algoritmo efficiente per la costruzione di un albero AVL dalla vasta collezione
Domanda
Ho una grande AVL albero che ho costruire alcune volte durante il programma da una collezione non ordinata (verrà usato per inserire / rimuovere gli elementi più tardi).
C'è un algoritmo di meglio che usare il semplice inserimento su ogni articolo? Sarà più efficace per ordinare la raccolta prima e poi cercare di costruire in modo diverso?
Profiling della mia candidatura mi dice che questo edificio AVL è un hotspot.
Soluzione
Se i dati comodamente inseriscono nella memoria, mi sarebbe davvero aspettare che facendo un Quicksort prima, e costruire l'albero da che sarebbe stato più veloce di fare tutte le inserzioni regolari.
Per costruire l'albero da una matrice, operano in modo ricorsivo, suddividendo l'albero in tre parti: un elemento centrale, la parte sinistra, e la parte destra; entrambe le parti devono avere la stessa dimensione (+ -1), quindi formare alberi fuori di queste parti. Ciò garantisce che l'albero risultante è quasi bilanciato (sarà perfettamente bilanciata se il numero di elementi è 2 ^ n-1). creazione Albero deve restituire l'altezza dell'albero in modo che si può mettere la bilancia comodamente in ogni nodo.
Modifica : Supponendo di Ian Piumarta tree.h , credo che questo algoritmo dovrebbe fare il trucco:
Node* tree_build(int key[], int value[], int L, int R) // L and R inclusive
{
int M;
Node *middle;
int lh, rh;
if(L == R)
return Node_new(key[L], value[L]);
if(L+1 == R) {
Node *left = Node_new(key[L], value[L]);
Node *right = Node_new(key[R], value[R]);
left->tree.avl_right = right;
left->tree.avl_height = 1;
return left;
}
// more than two nodes
M = L + (R-L)/2;
middle = Node_new(key[M], value[M]);
middle->tree.avl_left = tree_build(key, value, L, M-1);
middle->tree.avl_right = tree_build(key, value, M+1, R);
lh = middle->tree.avl_left->tree.avl_height;
rh = middle->tree.avl_right->tree.avl_height;
middle->tree.avl_height = 1 + (lh > rh ? lh:rh);
return middle;
}