String bilanciamento basato Binary Search albero (per il controllo ortografico)

voti
1

Update: Non posso ottenere Bilanciamento al lavoro, perché io non posso ottenere doAVLBalance per riconoscere le funzioni membro isBalanced (), isRightHeavy (), isLeftHeavy. E io non so perché! Ho provato l'esempio di Sash (3 ° risposta) esattamente ma ottengo la decelerazione è incompatibile e non ho potuto risolvere che ... così ho provato a fare a modo mio ... e mi dice non esistono quelle funzioni membro, quando hanno chiaramente fanno.

Errore: classe 'IntBinaryTree:.. TreeNode' non ha alcun membro 'isRightHeavy' Sono bloccato dopo aver provato per le ultime 4 ore :( codice aggiornato di seguito, l'aiuto sarebbe molto apprezzato !!

Sto creando una corda a base di Binary Search Albero e la necessità di farne un albero Balanced. Come faccio a fare questo? * Aiuto per favore !! Grazie in anticipo!

BinarySearchTree.cpp:

    bool IntBinaryTree::leftRotation(TreeNode *root)
    {
        //TreeNode *nodePtr = root;  // Can use nodePtr instead of root, better?
        // root, nodePtr, this->?

        if(NULL == root)
        {return NULL;}

        TreeNode *rightOfTheRoot = root->right;
        root->right = rightOfTheRoot->left;
        rightOfTheRoot->left = root;

        return rightOfTheRoot;
    }

    bool IntBinaryTree::rightRotation(TreeNode *root)
    {
        if(NULL == root)
        {return NULL;}
        TreeNode *leftOfTheRoot = root->left;
        root->left = leftOfTheRoot->right;
        leftOfTheRoot->right = root;

        return leftOfTheRoot;
    }

    bool IntBinaryTree::doAVLBalance(TreeNode *root)
    {


        if(NULL==root)
            {return NULL;}
        else if(root->isBalanced()) // Don't have isBalanced
            {return root;}

        root->left = doAVLBalance(root->left);
        root->right = doAVLBalance(root->right);

        getDepth(root); //Don't have this function yet

        if(root->isRightHeavy()) // Don't have isRightHeavey
        {
            if(root->right->isLeftheavey())
            {
                root->right = rightRotation(root->right);
            }
            root = leftRotation(root);
        }
        else if(root->isLeftheavey()) // Don't have isLeftHeavey
        {
            if(root->left->isRightHeavey())
            {
                root->left = leftRotation(root->left);
            }
            root = rightRotation(root);
        }
        return root;
    }

    void IntBinaryTree::insert(TreeNode *&nodePtr, TreeNode *&newNode)
    {
        if(nodePtr == NULL)
            nodePtr = newNode;                  //Insert node
        else if(newNode->value < nodePtr->value)
            insert(nodePtr->left, newNode);     //Search left branch
        else
            insert(nodePtr->right, newNode);    //search right branch
    }

//
// Displays the number of nodes in the Tree


int IntBinaryTree::numberNodes(TreeNode *root)
{
    TreeNode *nodePtr = root;

    if(root == NULL)
        return 0;

    int count = 1; // our actual node
    if(nodePtr->left !=NULL)
    { count += numberNodes(nodePtr->left);
    }
    if(nodePtr->right != NULL)
    {
        count += numberNodes(nodePtr->right);
    }
    return count;
} 

    // Insert member function

    void IntBinaryTree::insertNode(string num)
    {
        TreeNode *newNode; // Poitner to a new node.

        // Create a new node and store num in it.
        newNode = new TreeNode;
        newNode->value = num;
        newNode->left = newNode->right = NULL;

        //Insert the node.
        insert(root, newNode);
    }

    // More member functions, etc.

BinarySearchTree.h:

class IntBinaryTree
{
private:
    struct TreeNode
    {
        string value; // Value in the node
        TreeNode *left; // Pointer to left child node
        TreeNode *right; // Pointer to right child node
    };

    //Private Members Functions
    // Removed for shortness
    void displayInOrder(TreeNode *) const;


public:
    TreeNode *root;
    //Constructor
    IntBinaryTree()
        { root = NULL; }
    //Destructor
    ~IntBinaryTree()
        { destroySubTree(root); }

    // Binary tree Operations
    void insertNode(string);
    // Removed for shortness

    int numberNodes(TreeNode *root);
    //int balancedTree(string, int, int); // TreeBalanced

    bool leftRotation(TreeNode *root);
    bool rightRotation(TreeNode *root);
    bool doAVLBalance(TreeNode *root); // void doAVLBalance();
    bool isAVLBalanced();

    int calculateAndGetAVLBalanceFactor(TreeNode *root);

    int getAVLBalanceFactor()
    {
        TreeNode *nodePtr = root; // Okay to do this? instead of just
        // left->mDepth
        // right->mDepth

        int leftTreeDepth = (left !=NULL) ? nodePtr->left->Depth : -1;
        int rightTreeDepth = (right != NULL) ? nodePtr->right->Depth : -1;
        return(leftTreeDepth - rightTreeDepth);
    }

    bool isRightheavey() { return (getAVLBalanceFactor() <= -2); }

    bool isLeftheavey() { return (getAVLBalanceFactor() >= 2); }


    bool isBalanced()
    {
        int balanceFactor = getAVLBalanceFactor();
        return (balanceFactor >= -1 && balanceFactor <= 1);
    }


    int getDepth(TreeNode *root); // getDepth

    void displayInOrder() const
        { displayInOrder(root); }
    // Removed for shortness
};
È pubblicato 02/08/2011 alle 05:00
fonte dall'utente
In altre lingue...                            


3 risposte

voti
1

Ci sono molti modi per farlo, ma mi piacerebbe suggerire che non si effettivamente fare questo come tutti. Se si desidera memorizzare un BST di stringhe, ci sono opzioni migliori:

  1. Utilizzare un prewritten binario di classe di ricerca albero. Lo std :: set di classe C ++ offre le stesse garanzie di tempo come un equilibrato albero binario di ricerca ed è spesso implementato come tale. E 'sostanzialmente più facile da usare rispetto a rotazione si possiede BST.

  2. Utilizzare un trie, invece. La struttura dati trie è più semplice e più efficiente di un BST di stringhe, non richiede il bilanciamento a tutti, ed è più veloce di un BST.

Se davvero si deve scrivere il proprio BST equilibrato, avete molte opzioni. La maggior parte delle implementazioni BST che utilizzano il bilanciamento sono estremamente complessi e non sono per i deboli di cuore. Io suggerirei di attuazione sia un Treap o un albero splay, che sono due strutture BST bilanciati che sono piuttosto semplici da implementare. Sono entrambi più complessa di quanto il codice che avete sopra e non posso in questo breve spazio di fornire un'implementazione, ma una ricerca Wikipedia per queste strutture dovrebbero dare un sacco di consigli su come procedere.

Spero che questo ti aiuti!

Risposto il 02/08/2011 a 06:21
fonte dall'utente

voti
1

Purtroppo, noi programmatori sono bestie letterali.

ne fanno un albero "Balanced".

"Balanced" è dipendente dal contesto. Le classi strutture dati introduttivi in genere riferimento a un albero essere "bilanciata" quando la differenza tra il nodo di massima profondità e il nodo di minor profondità è minimizzata. Tuttavia, come detto da Sir Templatetypedef, un albero strombatura è considerato un albero di equilibratura. Questo è perché può bilanciare alberi piuttosto bene nei casi che pochi nodi accessibili insieme in una sola volta di frequente. Questo è perché ci vuole meno attraversamenti nodi per ottenere i dati in un albero splay di un albero binario convenzionale in questi casi . D'altra parte, le sue prestazioni nel caso peggiore su base di accesso-by-accesso può essere così grave come una lista collegata.

Parlando di liste collegate ...

Perché altrimenti, senza il "Bilanciamento" è lo stesso di una lista concatenata ho letto e sconfigge lo scopo.

Si può essere così male, ma per gli inserti randomizzati non lo è. Se si inserisce dati già ordinati, la maggior parte delle implementazioni binari di ricerca albero sarà memorizzare i dati come un gonfio e ordinò lista collegata. Tuttavia, è solo perché si sta costruendo un lato dell'albero di continuo. (Imagine inserimento 1, 2, 3, 4, 5, 6, 7, ecc ... in un albero binario. Prova su carta e vedere cosa succede.)

Se si dispone di bilanciare in senso worst-case-deve-garantito teorico, vi consiglio di guardare alberi rosso-neri. (Google, secondo link è piuttosto buona.)

Se si dispone di bilanciare in modo ragionevole per questo scenario particolare, mi piacerebbe andare con indici interi e una funzione di hash decente - in questo modo il bilanciamento avverrà probabilisticamente senza alcun codice aggiuntivo. Vale a dire, rendere la vostra funzione di confronto assomigliare hash (strA) <hash (STRB) al posto di quello che hai ora. (Per un hash rapido ma efficace per questo caso, cercare FNV hashing. Primo colpo su Google. Si scende fino a vedere il codice utile.) Si può preoccupare i dettagli di implementazione dell'efficienza, se si vuole. (Ad esempio, non è necessario effettuare sia hash ogni volta si confronta da quando una delle stringhe non cambia mai.)

Se si riesce a farla franca, vi raccomando vivamente questi ultimi, se siete in una crisi per il tempo e volete qualcosa di veloce. In caso contrario, alberi rosso-neri sono utili dato che sono estremamente utili nella pratica quando si ha bisogno di rotolare i propri alberi binari in altezza equilibrata.

Infine, affrontando il vostro codice di cui sopra, vedere i commenti nel codice qui sotto:

int IntBinaryTree::numberNodes(TreeNode *root)
{
    if(root = NULL) // You're using '=' where you want '==' -- common mistake.
                    // Consider getting used to putting the value first -- that is,
                    // "NULL == root". That way if you make that mistake again, the
                    // compiler will error in many cases.
        return 0;
    /*
    if(TreeNode.left=null && TreeNode.right==null)  // Meant to use '==' again.
    { return 1; }

    return numberNodes(node.left) + numberNodes(node.right);
    */

    int count = 1; // our actual node
    if (left != NULL)
    {
        // You likely meant 'root.left' on the next line, not 'TreeNode.left'.
        count += numberNodes(TreeNode.left);
        // That's probably the line that's giving you the error.
    }
    if (right != NULL)
    {
        count += numberNodes(root.right);
    }
    return count;
}
Risposto il 02/08/2011 a 08:10
fonte dall'utente

voti
1

I programmatori usano concetti AVL albero per equilibrare alberi binari. E 'molto semplice. Maggiori informazioni si possono trovare online. Wiki rapido collegamento

Di seguito è riportato il codice di esempio che fa equilibrio dell'albero utilizzando l'algoritmo AVL.

Node *BinarySearchTree::leftRotation(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    Node *rightOfTheRoot = root->mRight;
    root->mRight = rightOfTheRoot->mLeft;
    rightOfTheRoot->mLeft = root;

    return rightOfTheRoot;
}

Node *BinarySearchTree::rightRotation(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    Node *leftOfTheRoot = root->mLeft;
    root->mLeft = leftOfTheRoot->mRight;
    leftOfTheRoot->mRight = root;

    return leftOfTheRoot;
}

Node *BinarySearchTree::doAVLBalance(Node *root)
{
    if(NULL == root)
    {
        return NULL;
    }
    else if(root->isBalanced())
    {
        return root;
    }

    root->mLeft  = doAVLBalance(root->mLeft);
    root->mRight = doAVLBalance(root->mRight);

    getDepth(root);

    if(root->isRightHeavy())
    {
        if(root->mRight->isLeftHeavy())
        {
            root->mRight = rightRotation(root->mRight);
        }
        root = leftRotation(root);
    }
    else if(root->isLeftHeavy())
    {
        if(root->mLeft->isRightHeavy())
        {
            root->mLeft = leftRotation(root->mLeft);
        }
        root = rightRotation(root);
    }

    return root;
}

Classe Definizione

class BinarySearchTree
{
public:
    // .. lots of methods 
    Node *getRoot();
    int getDepth(Node *root);

    bool isAVLBalanced();
    int calculateAndGetAVLBalanceFactor(Node *root);
    void doAVLBalance();

private:
     Node *mRoot;
};

class Node
{
public:
    int  mData;
    Node *mLeft;
    Node *mRight;
    bool mHasVisited;
    int mDepth;
public:

    Node(int data)
    : mData(data),
      mLeft(NULL),
      mRight(NULL),
      mHasVisited(false),
      mDepth(0)
    {
    }

    int getData()              { return mData; }

    void setData(int data)     { mData = data;  }

    void setRight(Node *right) { mRight = right;}

    void setLeft(Node *left)   { mLeft = left; }

    Node * getRight()          { return mRight; }

    Node * getLeft()           { return mLeft; }

    bool hasLeft()             { return (mLeft != NULL);  }

    bool hasRight()            { return (mRight != NULL); }

    bool isVisited()           { return (mHasVisited == true); }

    int getAVLBalanceFactor()
    {
        int leftTreeDepth = (mLeft != NULL) ? mLeft->mDepth : -1;
        int rightTreeDepth = (mRight != NULL) ? mRight->mDepth : -1;
        return(leftTreeDepth - rightTreeDepth);
    }

    bool isRightHeavy() { return (getAVLBalanceFactor() <= -2); }

    bool isLeftHeavy()  { return (getAVLBalanceFactor() >= 2);  }

    bool isBalanced()
    {
        int balanceFactor = getAVLBalanceFactor();
        return (balanceFactor >= -1 && balanceFactor <= 1);
    }
};
Risposto il 02/08/2011 a 17:45
fonte dall'utente

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