Algoritmo efficiente per la costruzione di un albero AVL dalla vasta collezione

StackOverflow https://stackoverflow.com/questions/1295285

  •  18-09-2019
  •  | 
  •  

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.

È stato utile?

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top