Come migliorare l'efficienza della funzione che trova il numero di elementi in un intervallo da AVL albero?

voti
0

Sto scrivendo una funzione che viene a sapere il numero totale di elementi in un albero AVL di gamma. Ad esempio, gli argomenti che passavano in è ab e au, poi ho bisogno di sapere quanti elementi sono in un albero AVL è in tale intervallo.

Attualmente il mio modo di fare questo è quello di attraversare l'albero ogni volta quando il cliente lo chiama. Ma perché il numero di elementi nella mia AVL è albero di varia grande, ci vuole sempre se il cliente chiama questa funzione troppe volte. Esiste un modo più veloce per farlo?

La mia funzione gamma:

void range(AvlTree T, char* k1, char* k2) {
    if ( T == NULL )
        return;

    if ( strcmp(k1, T->Element) < 0 )
        range(T->Left, k1, k2);

    if ( strcmp(k1, T->Element) <= 0 && strcmp(k2, T->Element) >= 0 )
        total++;

    if ( strcmp(k2, T->Element) > 0 )
        range(T->Right, k1, k2);
}
È pubblicato 13/02/2020 alle 23:59
fonte dall'utente
In altre lingue...                            


1 risposte

voti
1

Il tuo attuale algoritmo ha una complessità di O (M + log N) dove N è la dimensione dell'albero e M è il numero di elementi all'interno della gamma . Non credo che si può fare di meglio con l'albero AVL annullamento della conversione. Quindi la soluzione comporterebbe cambiare l'implementazione albero.

Un modo semplice per farlo è quello di memorizzare in ciascun nodo della dimensione della sottostruttura in quel nodo. Queste informazioni possono essere aggiornate in tempo costante durante la rotazione dell'albero. Successivamente può essere usata per saltare interi sottoalberi come segue:

int range(AvlTree T, const char* k1, const char* k2) {
    assert(!k1 || !k2 || strcmp(k1, k2) <= 0);
    if(T == NULL)
        return 0;
    if(!k1 && !k2)
        return T->size;
    if(k2 && strcmp(k2, T->Element) < 0)
        return range(T->left, k1, k2);
    if(k1 && strcmp(T->Element, k1) < 0)
        return range(T->right, k1, k2);
    return range(T->left, k1, 0) + 1 + range(T->right, 0, k2);
}

Questo darebbe un O (log N) complessità.

NOTA BENE: il codice è testato.

Risposto il 14/02/2020 a 00:38
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more