Balanceren String gebaseerd Binary Search Tree (voor spellingcontrole)

stemmen
1

Update: Ik kan niet in evenwicht brengen om te werken, want ik kan niet doAVLBalance naar het lid functies isBalanced (), isRightHeavy (), isLeftHeavy herkennen. En ik weet niet waarom! Ik probeerde voorbeeld Sash's (3e antwoord) precies, maar ik krijg vertraging onverenigbaar is en ik kon niet vast te stellen dat ... dus ik probeerde het te doen op mijn manier ... en het vertelt me die lid functies niet bestaan, wanneer ze duidelijk doen.

Fout: class 'IntBinaryTree:.. TreeNode' heeft geen enkel lid 'isRightHeavy' Ik ben vast na het proberen voor de laatste 4 uur :( Bijgewerkt onderstaande code, hulp zou zeer gewaardeerd worden !!

Ik ben het creëren van een String gebaseerd Binary Search Tree en de noodzaak om het een Balanced boom te maken. Hoe doe ik dit? * Help please !! Bij voorbaat dank!

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
};
De vraag is gesteld op 02/08/2011 om 05:00
bron van user
In andere talen...                            


3 antwoorden

stemmen
1

Er zijn vele manieren om dit te doen, maar ik stel dat je eigenlijk niet doen omdat alle. Als u wilt een BST van strings op te slaan, zijn er veel betere opties:

  1. Gebruik een vooraf geschreven binaire zoekboom klasse. De C ++ std :: set klasse biedt tegelijk garanties als een evenwichtige binaire zoekboom en wordt vaak toegepast als zodanig. Het is aanzienlijk gemakkelijker te gebruiken dan rollen u eigenaar BST.

  2. Gebruik een trie plaats. De trie datastructuur is eenvoudiger en efficiënter dan een BST snaren, hoeft zich niet te balanceren helemaal niet, en is sneller dan een BST.

Als je moet echt je eigen evenwicht BST te schrijven, heb je veel mogelijkheden. De meeste BST implementaties die balancing gebruiken zijn uiterst complex en zijn niet voor bangeriken. Ik stel voor de uitvoering van ofwel een treap of een splayboom, die twee gebalanceerde BST structuren die eerder zijn eenvoudig toe te passen zijn. Ze zijn allebei complexer dan de code in die u hierboven heb en ik kan niet in deze korte ruimte te bieden een implementatie, maar een Wikipedia zoektocht naar deze structuren moet u veel advies over hoe verder te gaan geven.

Ik hoop dat dit helpt!

antwoordde op 02/08/2011 om 06:21
bron van user

stemmen
1

Helaas, we programmeurs zijn letterlijke beesten.

maak er een "Balanced" boom.

"Balanced" is afhankelijk van de context. De inleidende datastructuren klassen meestal verwijzen naar een boom die "evenwichtige" wanneer het verschil tussen het knooppunt van de grootste diepte en het knooppunt van de minste diepte wordt geminimaliseerd. Echter, zoals genoemd door Sir Templatetypedef, een splayboom wordt beschouwd als een balanceren boom. Dit is omdat het bomen in balans kunnen brengen vrij goed in de gevallen dat er maar weinig nodes op een bepaald moment vaak samen benaderd. Dit is omdat het duurt minder knooppunt traversals om bij de gegevens in een splayboom dan een conventionele binaire boom in deze gevallen . Aan de andere kant kan de worst-case prestaties op een toegangspunt-by-toegang basis zo slecht als een gekoppelde lijst zijn.

Spreken van gelinkte lijsten ...

Want anders zonder de "in evenwicht brengen" het is hetzelfde als een gekoppelde-list Ik lees en verslaat het doel.

Het kan zo slecht zijn, maar voor gerandomiseerde inserts is het niet. Als u al gesorteerde gegevens in te voegen, zullen de meeste binaire zoekboom implementaties data als een opgeblazen slaan en bestelde gekoppelde lijst. Maar dat is alleen maar omdat je één kant van de boom voortdurend aan het bouwen bent. (Stel je voor het invoegen van 1, 2, 3, 4, 5, 6, 7, etc ... in een binaire boom. Probeer het op papier en zien wat er gebeurt.)

Als je moet in evenwicht in een theoretisch worst-case-must-gegarandeerde sense, adviseer ik het opzoeken van rood-zwarte bomen. (Google het, tweede link is vrij goed.)

Als je moet het evenwicht in een redelijke manier voor dit specifieke scenario, zou ik ga met integer indices en een fatsoenlijke hash-functie - op die manier het in evenwicht zal probabilistisch gebeuren zonder extra code. Dat wil zeggen, maak je vergelijking functie eruit hash (strA) <hash (STRB) in plaats van wat je nu hebt. (Voor een snelle maar effectieve hash in dit geval, kijk omhoog FNV hashing. In de eerste hit op Google. Ga naar beneden tot u nuttige code.) U kunt zorgen te maken over de details van de uitvoering efficiëntie als je wilt. (Bijvoorbeeld, hoef je niet uit te voeren zowel hashes elke keer dat je het vergelijkt omdat een van de snaren nooit verandert.)

Als je ermee weg kan komen, adviseer ik sterk de laatste als je in een crunch voor tijd en willen iets snel. Anders, rood-zwarte bomen zijn de moeite waard omdat ze zeer nuttig in de praktijk wanneer je nodig hebt om je eigen lengte evenwichtige binaire bomen rollen.

Tot slot, het aanpakken van uw bovenstaande code, zie de opmerkingen in de onderstaande code:

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;
}
antwoordde op 02/08/2011 om 08:10
bron van user

stemmen
1

Programmeurs gebruiken AVL Tree concepten om binaire bomen in evenwicht te brengen. Het is heel simpel. Meer informatie kan online worden gevonden. Quick wiki koppeling

Hieronder ziet u het monster code die boom weegschaal met AVL algoritme doet.

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

class Definition

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);
    }
};
antwoordde op 02/08/2011 om 17:45
bron van user

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