Echilibrarea String bazat binar de căutare Arbore (pentru gramaticală)

voturi
1

Actualizare: Eu nu pot obține „echilibrare“ la locul de muncă, pentru că nu pot obține „doAVLBalance“ să recunoască funcțiile de membru „isBalanced ()“, „isRightHeavy ()“, „isLeftHeavy“. Și eu nu știu de ce! Am încercat exemplul lui Sash (răspuns 3 -a ) exact , dar am obține „decelerația este incompatibil“ și nu am putut repara asta ... așa că am încercat o fac în felul meu ... și mi -a spus aceste funcții membre nu există, atunci când acestea fac în mod clar.

„Eroare: clasa«IntBinaryTree:.. TreeNode»nu are nici un membru«isRightHeavy»Sunt blocat după ce a încercat pentru ultimele 4 ore :( cod Actualizat mai jos, ajutor ar fi mult mai apreciat !!

Creez un șir binar de căutare pe bază de copac și trebuie să - l un „echilibrat“ copac face. Cum pot face acest lucru? * Ajutor va rog !! Mulțumesc anticipat!

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
};
Întrebat 02/08/2011 la 05:00
sursa de către utilizator
În alte limbi...                            


3 răspunsuri

voturi
1

Există mai multe modalități de a face acest lucru, dar mi-ar sugera că de fapt, nu face acest lucru ca toți. Dacă doriți să stocați un BST de siruri de caractere, există opțiuni mult mai bune:

  1. Utilizați un binar clasă de căutare copac scris dinainte. C ++ std :: set clasa oferă aceleași garanții de timp ca un arbore echilibrat binar de căutare și este adesea pus în aplicare ca atare. Este în mod substanțial mai ușor de utilizat decât rulare dețineți BST.

  2. Utilizați un trie în loc. Structura de date trie este mai simplă și mai eficientă decât o BST de siruri de caractere, nu necesită echilibrare, la toate, și este mai rapid decât un BST.

Dacă într-adevăr trebuie să scrie opinia ta BST echilibrat, aveți mai multe opțiuni. Cele mai multe implementari BST care folosesc echilibrare sunt extrem de complexe și nu sunt pentru cei slabi de inimă. Aș sugera de punere în aplicare, fie un treap sau un arbore splay, care sunt două structuri BST echilibrate, care sunt destul de simple pentru a pune în aplicare. Sunt atât mai complexe decât codul aveți de mai sus și nu pot în acest spațiu scurt oferă o implementare, dar o căutare pe Wikipedia pentru aceste structuri ar trebui să vă dea o multime de sfaturi despre cum să procedeze.

Sper că acest lucru vă ajută!

Publicat 02/08/2011 la 06:21
sursa de către utilizator

voturi
1

Din păcate, noi programatorii sunt animale literale.

face un „echilibrat“ copac.

„Echilibrat“ este dependentă de context. Structurile de date introductive clase de obicei se referă la un copac fiind „echilibrat“ , atunci când diferența dintre nodul de mare adâncime și nodul de cel puțin adâncimea este redusă la minimum. Cu toate acestea, după cum sa menționat de Sir Templatetypedef, un arbore splay este considerat un arbore de echilibrare. Acest lucru se datorează faptului că poate echilibra copaci destul de bine în cazurile în care puține noduri accesate împreună la un moment dat în mod frecvent. Acest lucru se datorează faptului că este nevoie de mai puțin traversări nod pentru a ajunge la datele într - un copac splay decât un arbore binar convențional , în aceste cazuri . Pe de altă parte, performanțele sale cel mai rău caz , pe o bază de acces de acces poate fi la fel de rău ca o listă înlănțuită.

Vorbind de liste legate de ...

Pentru că altfel fără „echilibrare“ este la fel ca și o listă legată am citit și învinge scopul.

Acesta poate fi la fel de rău, dar pentru inserții randomizate nu este. Dacă introduceți date deja sortate, cele mai multe implementari binare de căutare copac va stoca date , cum ar fi un umflat și a dispus lista legată. Cu toate acestea, asta e doar pentru că sunteți construirea o parte a copacului continuu. (Imaginați - vă inserarea 1, 2, 3, 4, 5, 6, 7, etc ... intr - un arbore binar. Încearcă - l pe hârtie și să vedem ce se întâmplă.)

Dacă trebuie să echilibreze într-un sens cel mai rău caz, trebuie să-garantate teoretic, recomand în căutarea copaci roșu-negru. (Google o, a doua link-ul este destul de bun.)

Dacă trebuie să-l echilibru într-un mod rezonabil pentru acest scenariu special, aș merge cu indici întregi și o funcție hash decent - în acest fel echilibrarea se va întâmpla în mod probabilist, fără nici un cod suplimentar. Adică, face funcția de comparație arata ca hash (strA) <diez (strB) în loc de ceea ce ai acum. (Pentru un hash rapid, dar eficient pentru acest caz, privi în sus FNV hashing. Primul lovit pe Google. Du-te în jos până la codul util.) Puteți face griji cu privire la detaliile de implementare a eficienței, dacă doriți să. (De exemplu, nu trebuie să îndeplinească ambele hash-uri de fiecare dată când compara, deoarece unul dintre șirurile nu se schimbă niciodată.)

Dacă puteți obține departe cu ea, eu recomand aceasta din urmă, dacă vă aflați într-o criză de timp și doresc ceva rapid. În caz contrar, copaci rosu-negru sunt valoroase, deoarece acestea sunt extrem de utile în practică, atunci când trebuie să se rostogolească propriile arbori binari înălțime echilibrată.

În cele din urmă, abordarea codul de mai sus, a se vedea comentariile din codul de mai jos:

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;
}
Publicat 02/08/2011 la 08:10
sursa de către utilizator

voturi
1

Programatorii folosesc concepte AVL copac pentru a echilibra arbori binari. Este destul de simplu. Mai multe informații pot fi găsite online. Wiki Quick link

Mai jos este codul de probă care se echilibrează cu ajutorul arborelui AVL algoritm.

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;
}

Clasa Definiție

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);
    }
};
Publicat 02/08/2011 la 17:45
sursa de către utilizator

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