Εξισορρόπηση String με βάση Binary Search Tree (για ορθογραφικό έλεγχο)

ψήφοι
1

Ενημέρωση: Δεν μπορώ να πάρω «Εξισορρόπηση» για να εργαστεί, γιατί δεν μπορώ να πάρω «doAVLBalance» για να αναγνωρίσει τις συναρτήσεις-μέλη «isBalanced ()», «isRightHeavy ()», «isLeftHeavy». Και δεν ξέρω γιατί! Προσπάθησα παράδειγμα φύλλου του (3ος απάντηση) ακριβώς, αλλά έχω «επιβράδυνση είναι ασυμβίβαστη» και δεν μπορούσα να το διορθώσουμε ... Γι 'αυτό προσπάθησα να κάνει το δρόμο μου ... και μου λέει δεν υπάρχουν αυτές οι λειτουργίες μέλος, όταν που προφανώς κάνουν.

«Σφάλμα: class“IntBinaryTree:.. TreeNode”δεν έχει κανένα μέλος“isRightHeavy”Είμαι κολλημένος μετά από προσπάθεια για τις τελευταίες 4 ώρες :( Ενημέρωση παρακάτω κώδικα, βοήθεια θα ήταν πολύ ευπρόσδεκτη !!

Είμαι δημιουργώντας ένα String με βάση Binary Search Tree και πρέπει να γίνει μια «ισορροπημένη» δέντρο κάνει. Πώς το κάνω αυτό? * Βοήθεια παρακαλώ !! Ευχαριστώ εκ των προτέρων!

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
};
Δημοσιεύθηκε 02/08/2011 στις 05:00
πηγή χρήστη
Σε άλλες γλώσσες...                            


3 απαντήσεις

ψήφοι
1

Υπάρχουν πολλοί τρόποι να γίνει αυτό, αλλά θα ήθελα να προτείνω ότι μπορείτε πραγματικά δεν το κάνετε αυτό, όπως όλοι. Αν θέλετε να αποθηκεύσετε μια BST των χορδών, υπάρχουν πολύ καλύτερες επιλογές:

  1. Χρησιμοποιήστε ενός προκαθορισμένου δυαδική τάξη δέντρο αναζήτησης. Η ++ std :: οριστεί κατηγορίας C προσφέρει την ίδια στιγμή εγγυήσεις ως μια ισορροπημένη δυαδικό δέντρο αναζήτησης και συχνά υλοποιείται ως τέτοια. Είναι ουσιαστικά πιο εύκολο στη χρήση από τροχαίο είστε ιδιοκτήτης BST.

  2. Χρησιμοποιήστε ένα trie αντ 'αυτού. Η δομή δεδομένων Trie είναι απλούστερη και πιο αποτελεσματική από ό, τι ένα BST των χορδών, δεν απαιτεί εξισορρόπηση σε όλα, και είναι πιο γρήγορα από ό, τι ένα BST.

Αν πραγματικά πρέπει να γράψετε τη δική σας βάση BST, έχετε πολλές επιλογές. Οι περισσότερες εφαρμογές BST που χρησιμοποιούν την εξισορρόπηση είναι εξαιρετικά πολύπλοκο και δεν είναι για τον εξασθενημένο της καρδιάς. Θα πρότεινα την εφαρμογή είτε treap ή ένα δέντρο άτεχνος, που είναι δύο ισορροπημένες δομές BST που είναι μάλλον απλή στην εφαρμογή της. Είναι και οι δύο πιο περίπλοκη από ό, τι τον κωδικό που έχετε παραπάνω και δεν μπορώ σε αυτό το σύντομο διάστημα παρέχουν μια εφαρμογή, αλλά μια αναζήτηση Wikipedia για αυτές τις δομές θα πρέπει να σας δώσει πολλές συμβουλές για το πώς να προχωρήσουμε.

Η ελπίδα αυτό βοηθά!

Απαντήθηκε 02/08/2011 στις 06:21
πηγή χρήστη

ψήφοι
1

Δυστυχώς, οι προγραμματιστές είναι κυριολεκτική θηρία.

να κάνουν μια «ισορροπημένη» δέντρο.

«Ισορροπημένη» είναι το πλαίσιο εξαρτάται. Οι τάξεις εισαγωγικές δομές δεδομένων συνήθως αναφέρονται σε ένα δέντρο είναι «ισορροπημένη», όταν η διαφορά μεταξύ του κόμβου από τις μεγαλύτερες βάθος και τον κόμβο των λιγότερο βάθος ελαχιστοποιείται. Ωστόσο, όπως αναφέρθηκε από τον Sir Templatetypedef, ένα δέντρο άτεχνος θεωρείται εξισορρόπηση δέντρο. Αυτό οφείλεται στο γεγονός ότι μπορεί να ισορροπήσει τα δέντρα αρκετά καλά στις περιπτώσεις που λίγοι κόμβοι πρόσβαση από κοινού σε ένα χρόνο συχνά. Αυτό συμβαίνει γιατί χρειάζεται λιγότερο διελεύσεις κόμβο για να πάρει τα δεδομένα σε ένα δέντρο άτεχνος από ένα συμβατικό δυαδικό δέντρο σε αυτές τις περιπτώσεις . Από την άλλη πλευρά, οι επιδόσεις της χειρότερης περίπτωσης της υπό συνθήκες πρόσβασης προς πρόσβασης μπορεί να είναι τόσο κακή όσο μια συνδεδεμένη λίστα.

Μιλώντας για συνδεδεμένες λίστες ...

Διότι αλλιώς, χωρίς το «Εξισορρόπηση» είναι το ίδιο με μια συνδεδεμένη λίστα διάβασα και εξυπηρετεί το σκοπό.

Αυτό μπορεί να είναι τόσο κακό, αλλά για τυχαία ένθετα δεν είναι. Αν τοποθετήσετε ήδη ταξινομημένα δεδομένα, οι περισσότεροι δυαδικό εφαρμογές δέντρο αναζήτησης θα αποθηκεύει τα δεδομένα σαν μια φουσκωμένη και διέταξε συνδεδεμένη λίστα. Ωστόσο, αυτό είναι μόνο και μόνο επειδή είστε οικοδόμηση μια πλευρά του δέντρου συνεχώς. (Φανταστείτε την εισαγωγή 1, 2, 3, 4, 5, 6, 7, κλπ ... σε ένα δυαδικό δέντρο. Δοκιμάστε το σε χαρτί και να δούμε τι θα συμβεί.)

Αν έχετε να ισορροπήσει σε ένα θεωρητικό χειρότερη περίπτωση, θα πρέπει να εγγύηση έννοια, ήθελα να συστήσω ανατρέχοντας κόκκινο-μαύρο δέντρα. (Το Google, το δεύτερο link είναι αρκετά καλή.)

Αν έχετε να ισορροπήσει σε ένα λογικό τρόπο για το συγκεκριμένο σενάριο, θα πήγαινα με τους δείκτες ακέραιο και ένα αξιοπρεπές συνάρτηση κατακερματισμού - αυτόν τον τρόπο η εξισορρόπηση θα συμβεί πιθανολογικά χωρίς καμία επιπλέον κώδικα. Δηλαδή, κάνει τη λειτουργία Σύγκρισης μοιάζουν hash (strA) <hash (STRB) αντί για αυτό που έχετε τώρα. (Για μια γρήγορη, αλλά αποτελεσματική hash για την περίπτωση αυτή, κοιτάζω προς τα πάνω FNV κατακερματισμού. Πρώτο χτύπημα στο Google. Πηγαίνετε προς τα κάτω μέχρι να δείτε χρήσιμες κωδικό.) Μπορείτε να ανησυχείτε για τις λεπτομέρειες της αποτελεσματικότητας της εφαρμογής, αν θέλετε να. (Για παράδειγμα, δεν χρειάζεται να εκτελέσετε δύο hashes κάθε φορά που συγκρίνουν δεδομένου ότι μία από τις χορδές δεν αλλάζει ποτέ.)

Εάν μπορείτε να πάρετε μακριά με αυτό, σας συνιστώ ανεπιφύλακτα το τελευταίο, αν είστε σε μια κρίσιμη στιγμή για το χρόνο και θέλουν κάτι γρήγορο. Διαφορετικά, κόκκινο-μαύρο δέντρα αξίζουν τον κόπο δεδομένου ότι είναι εξαιρετικά χρήσιμη στην πράξη, όταν θα πρέπει να κυλήσει το δικό σας ύψος ισορροπημένη δυαδικά δέντρα.

Τέλος, αντιμετωπίζοντας τον κωδικό σας παραπάνω, δείτε τα σχόλια στον παρακάτω κώδικα:

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;
}
Απαντήθηκε 02/08/2011 στις 08:10
πηγή χρήστη

ψήφοι
1

Οι προγραμματιστές χρησιμοποιούν έννοιες AVL δέντρο να ισορροπήσει δυαδικά δέντρα. Είναι πολύ απλό. Περισσότερες πληροφορίες μπορείτε να βρείτε στο διαδίκτυο. Γρήγορη wiki σύνδεση

Παρακάτω είναι το δείγμα κώδικα που κάνει την ισορροπία δέντρο χρησιμοποιώντας τον αλγόριθμο 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;
}

Κατηγορία Ορισμός

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);
    }
};
Απαντήθηκε 02/08/2011 στις 17:45
πηγή χρήστη

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