Balancing String basierend binärer Suchbaum (Überprüfen der Rechtschreibung)

stimmen
1

Update: Ich kann nicht „Balancing“ zu arbeiten, weil ich nicht „doAVLBalance“ bekommen kann die Mitgliederfunktionen „isBalanced ()“, „isRightHeavy ()“, „isLeftHeavy“ zu erkennen. Und ich weiß nicht , warum! Ich habe versucht , Sash das Beispiel (3. Antwort) genau , aber ich erhalte „Verzögerung ist nicht kompatibel“ und ich konnte das nicht beheben ... und so versuchte ich es auf meine Weise tun ... und es sagt mir , diese Mitgliederfunktionen nicht existieren, wenn sie klar.

„Fehler: Klasse‚IntBinaryTree:.. TreeNode‘hat kein Mitglied‚isRightHeavy‘Ich bin fest, nachdem für die letzten 4 Stunden mit dem Versuch :( Aktualisiert Code unten, Hilfe sehr geschätzt würde !!

Ich erstelle eine String basierend binärer Suchbaum und müssen , um es ein „Balanced“ Baum. Wie mache ich das? * Hilfe bitte !! Danke im Voraus!

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
};
Veröffentlicht am 02/08/2011 um 05:00
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
1

Es gibt viele Möglichkeiten, dies zu tun, aber ich würde vorschlagen, dass Sie tatsächlich diese wie alle nicht. Wenn Sie ein BST von Strings gespeichert werden sollen, gibt es viel bessere Möglichkeiten:

  1. Verwenden Sie eine prewritten binäre Suchbaum-Klasse. Die C ++ std :: set-Klasse bietet garantiert gleichzeitig als eine ausgeglichene binäre Suchbaum und wird oft als solche umgesetzt. Es ist wesentlich einfacher zu benutzen als Sie BST besitzen rollen.

  2. Verwenden Sie stattdessen eine trie. Die Trie-Datenstruktur ist einfacher und effizienter als ein BST von Strings, erfordert überhaupt keinen Ausgleich, und ist schneller als ein BST.

Wenn Sie wirklich Ihre eigene ausgewogen BST schreiben müssen, haben Sie viele Möglichkeiten. Die meisten BST-Implementierungen, den Ausgleich verwenden sind äußerst komplex und sind nicht für schwache Nerven. Ich würde vorschlagen, entweder eine Treap oder einen gespreizten Baum Implementierung, die zwei symmetrische BST Strukturen sind, die relativ einfach zu implementieren ist. Sie sind beide komplexer als der Code, den Sie oben haben, und ich kann in dieser kurzen keine Implementierung zur Verfügung stellen, sondern eine Wikipedia-Suche für diese Strukturen sollten Ihnen viele Ratschläge, wie zu verfahren.

Hoffe das hilft!

Beantwortet am 02/08/2011 um 06:21
quelle vom benutzer

stimmen
1

Leider sind wir Programmierer wörtliche Tiere.

macht es zu einem „Balanced“ Baum.

„Balanced“ ist kontextabhängig. Die einführenden Datenstrukturen Klassen beziehen sich typischerweise auf einen Baum „balanced“ , wenn die Differenz zwischen dem Knotenpunkt mit der größten Tiefe und dem Knoten des geringsten Tiefe minimiert wird. Wie jedoch von Sir Templatetypedef erwähnte, wird ein Spreizfuß Baum einen Ausgleich Baum betrachtet. Dies liegt daran , es Bäume ziemlich gut in Fällen , dass einige Knoten zugegriffen zusammen zu einer Zeit häufig ausgleichen kann. Dies ist , weil es weniger Knoten Traversierungen nimmt an den Daten in einem gespreizten Baum zu erhalten als bei einem herkömmlichen binären Baum in diesen Fällen . Auf der anderen Seite, seine Worst-Case - Performance auf einer Access-by-Access - Basis kann so schlecht , wie eine verknüpfte Liste sein.

Apropos verkettete Listen ...

Denn sonst ohne die „Balancing“ es ist das gleiche wie eine verknüpfte Liste Ich habe gelesen und Niederlagen der Zweck.

Es kann so schlimm sein, aber für randomisierte Einsätze ist es nicht. Wenn Sie bereits sortierte Daten einfügen, werden die meisten binäre Suchbaum - Implementierungen speichern Daten wie eine aufgeblähte und geordnete Liste verknüpft. Aber das ist nur , weil Sie eine Seite des Baumes ständig zu bauen. (Man stelle 1 Einsetzen, 2, 3, 4, 5, 6, 7, usw ... in einen binären Baum. Versuchen Sie es auf dem Papier sehen , was passiert.)

Wenn Sie in einem theoretischen Worst-Case-muss garantierten Sinn zum Ausgleich haben, empfehle ich auf der Suche rot-schwarze Bäume. (Google es ist zweite Verbindung ziemlich gut.)

Wenn Sie es in einer angemessenen Art und Weise für dieses spezielle Szenario zum Ausgleich haben, würde ich mit Integer-Indizes und einer anständigen Hash-Funktion gehen - diese Art und Weise des Ausgleich probabilistically ohne zusätzlichen Code passieren wird. Das heißt, machen Sie Ihre Vergleichsfunktion wie Hash aussehen (strA) <hash (strB) statt, was du jetzt hast. (Für eine schnelle, aber effektive Hash für diesen Fall, FNV Hashing nachzuschlagen. Erster Erfolg auf Google. Gehen Sie nach unten, bis Sie nützliche Code.) Sie können über die Details der Umsetzung Effizienz sorgen, wenn Sie wollen. (Beispiel: Sie müssen nicht erfüllen beide Hashes jedes einzelne Mal, wenn Sie da eine der Saiten vergleichen ändert sich nie.)

Wenn Sie damit durchkommen kann, empfehle ich die letztere, wenn Sie in einem Knirschen für Zeit und wollen etwas schnell. Ansonsten sind rot-schwarz Bäume lohnt sich, da sie in der Praxis sehr nützlich sind, wenn Sie Ihre eigene Höhe ausgewogene Binärbäumen müssen rollen.

Schließlich Ihr Code oben Adressierung finden Sie in den Kommentaren in dem folgenden 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;
}
Beantwortet am 02/08/2011 um 08:10
quelle vom benutzer

stimmen
1

Programmierer verwenden AVL - Baum Konzepte Binärbäumen zu balancieren. Es ist ganz einfach. Weitere Informationen hierzu finden Sie online. Schnell Wiki Link

mit AVL-Algorithmus Unten ist der Code Probe, die Baum Gleichgewicht der Fall ist.

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

Klassendefinition

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);
    }
};
Beantwortet am 02/08/2011 um 17:45
quelle vom benutzer

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