Qual è la complessità temporale di questo programma?

3

Viene fornito un algoritmo su GeeksForGeeks.com per la costruzione di un albero di ricerca binario dal suo preorder traversal.

Dicono che la complessità temporale per il codice seguente è O (n ^ 2). Ma secondo me dovrebbe essere O (nlogn). Sono fiducioso sul calcolo di O () per la maggior parte degli algoritmi, ma qui c'è un algoritmo divide and conquer, che viene eseguito come T(n) = T(n/2) + O(n) , che a mio avviso dovrebbe funzionare in O (nlogn) con il metodo master?

Qualcuno può dirmi quanto la complessità sia O (n ^ 2)?

L'idea del codice è:

The first element of preorder traversal is always root. We first construct the root. Then we find the index of first element which is greater than root. Let the index be ‘i’. The values between root and ‘i’ will be part of left subtree, and the values between ‘i+1′ and ‘n-1′ will be part of right subtree. Divide given pre[] at index “i” and recur for left and right sub-trees.

For example in {10, 5, 1, 7, 40, 50}, 10 is the first element, so we make it root. Now we look for the first element greater than 10, we find 40.

struct node
{
    int data;
    struct node *left;
    struct node *right;
};

// A utility function to create a node
struct node* newNode (int data)
{
    struct node* temp = (struct node *) malloc( sizeof(struct node) );
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}

// A recursive function to construct Full from pre[]. preIndex is used
// to keep track of index in pre[].
struct node* constructTreeUtil (int pre[], int* preIndex,
                            int low, int high, int size)
{
    // Base case
    if (*preIndex >= size || low > high)
        return NULL;

    // The first node in preorder traversal is root. So take the node at
    // preIndex from p re[] and make it root, and increment preIndex
    struct node* root = newNode ( pre[*preIndex] );
    *preIndex = *preIndex + 1;

        // If the current subarry has only one element, no need to recur
    if (low == high)
        return root;

    // Search for the first element greater than root
    int i;
    for ( i = low; i <= high; ++i )
        if ( pre[ i ] > root->data )
            break;

    // Use the index of element found in postorder to divide postorder array in
    // two parts. Left subtree and right subtree
    root->left = constructTreeUtil ( pre, preIndex, *preIndex, i - 1, size );
    root->right = constructTreeUtil ( pre, preIndex, i, high, size );

    return root;
}

// The main function to construct BST from given preorder traversal.
// This function mainly uses constructTreeUtil()
struct node *constructTree (int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil (pre, &preIndex, 0, size - 1, size);
}
    
posta Dhruv Mullick 23.07.2015 - 23:51
fonte

1 risposta

2

Mentre l'algoritmo dichiarato è O (n log n) nel caso medio, è O (n ^ 2) nel caso peggiore, cioè quando viene usato per ricostruire un albero in cui ogni nodo ha un ramo vuoto o al suo sinistra o destra. Tale albero ha una profondità di n, e quindi l'algoritmo ricorre n volte, ogni ricorsione che richiede una media di confronti n / 2 da completare.

    
risposta data 24.07.2015 - 01:54
fonte

Leggi altre domande sui tag