Équilibre chaîne binaire basé arbre de recherche (pour la correction orthographique)

voix
1

Mise à jour: Je ne peux pas obtenir « équilibre » au travail, parce que je ne peux pas « doAVLBalance » pour reconnaître les fonctions membres « isBalanced () », « isRightHeavy () », « isLeftHeavy ». Et je ne sais pas pourquoi! J'ai essayé l'exemple de Sash (3e réponse) exactement , mais je reçois « décélération est incompatible » et je ne pouvais pas arranger ça ... donc j'essayé de faire mon chemin ... et il me dit ces fonctions membres n'existent pas, quand ils le font clairement.

« Erreur: classe « IntBinaryTree:.. TreeNode » n'a pas membre « isRightHeavy » Je suis coincé après avoir essayé pendant les 4 dernières heures :( Mise à jour du code ci-dessous, aide serait très apprécié !!

Je crée une chaîne binaire basé arbre de recherche et la nécessité de faire un arbre « équilibré ». Comment puis-je faire cela? * Aide s'il vous plaît !! Merci d'avance!

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
};
Créé 02/08/2011 à 05:00
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
1

Il y a plusieurs façons de le faire, mais je vous suggère que vous en fait pas cela comme tout. Si vous souhaitez enregistrer un BST de chaînes, il y a beaucoup de meilleures options:

  1. Utilisez une classe d'arbre de recherche binaire pré-écrite. Le C ++ classe std :: ensemble offre les mêmes garanties de temps comme un arbre binaire équilibré et est souvent mis en œuvre en tant que telle. Il est beaucoup plus facile à utiliser que vous possédez rouler BST.

  2. Utilisez un Trie la place. La structure de données arborescente est plus simple et plus efficace qu'un BST de chaînes, ne nécessite aucun équilibrage du tout, et est plus rapide qu'un BST.

Si vous devez vraiment écrire votre propre BST équilibré, vous avez beaucoup d'options. La plupart des implémentations de BST qui utilisent l'équilibrage sont extrêmement complexes et ne sont pas pour les faibles de cœur. Je vous suggère de mettre en œuvre soit un Treap ou un arbre évasement, qui sont deux structures BST équilibrées qui sont assez simples à mettre en œuvre. Ils sont à la fois plus complexe que le code que vous avez ci-dessus et je ne peux pas dans ce court espace fournir une implémentation, mais une recherche Wikipedia pour ces structures devraient vous donner beaucoup de conseils sur la façon de procéder.

J'espère que cela t'aides!

Créé 02/08/2011 à 06:21
source utilisateur

voix
1

Malheureusement, nous les programmeurs sont des bêtes littérales.

faire un arbre « équilibré ».

« Équilibrée » dépend du contexte. Les classes de structures de données d' introduction font généralement référence à un arbre étant « équilibré » lorsque la différence entre le noeud de plus grande profondeur et le nœud du moins la profondeur est réduite au minimum. Cependant, comme mentionné par Sir Templatetypedef, un arbre évasement est considéré comme un arbre d' équilibrage. En effet , il peut équilibrer les arbres plutôt bien dans les cas que peu de nœuds accessibles en même temps à un moment donné fréquemment. En effet , il prend moins de nœud traversals pour obtenir les données dans un arbre évasement qu'un arbre binaire classique dans ces cas . D'autre part, sa pire performance cas sur une base d' accès par l' accès peut être aussi mauvais que d' une liste liée.

En parlant de listes chaînées ...

Parce que sinon, sans le « équilibre », il est comme une liste chaînée je lis et défaites le but.

Il peut être aussi mauvais, mais pour les insertions aléatoires n'est pas. Si vous insérez des données déjà triées, la plupart des implémentations d'arbres de recherche binaires stockent des données comme une liste pléthorique et liée ordonné. Cependant, c'est seulement parce que vous construisez un côté de l'arbre sans cesse. (Imaginez insérer 1, 2, 3, 4, 5, 6, 7, etc ... dans un arbre binaire. Essayez - le sur du papier et de voir ce qui se passe.)

Si vous devez équilibrer dans un sens théorique du pire cas doit-garantie, je vous recommande de regarder les arbres rouge-noir. (Google il, second lien est assez bon.)

Si vous devez équilibrer d'une manière raisonnable pour ce scénario particulier, je partirais avec des indices entiers et une fonction de hachage décent - cette façon, l'équilibre se produira sans probabilistes de code supplémentaire. C'est-à-dire que votre fonction de comparaison ressembler à hachage (STRA) <hachage (strB) au lieu de ce que vous avez maintenant. (Pour un hachage rapide mais efficace pour ce cas, rechercher hashing FNV. Hit premier sur Google. Aller en bas jusqu'à ce que le code utile.) Vous pouvez vous soucier des détails de l'efficacité de la mise en œuvre si vous voulez. (Par exemple, vous ne devez pas exécuter les deux hachages chaque fois que vous comparez depuis l'une des chaînes ne change jamais.)

Si vous pouvez vous en sortir avec elle, je vous recommande vivement ce dernier si vous êtes dans une situation critique pour le temps et que vous voulez quelque chose de rapide. Dans le cas contraire, les arbres rouge-noir en valent la peine, car ils sont extrêmement utiles dans la pratique lorsque vous avez besoin de rouler vos propres arbres binaires hauteur équilibrée.

Enfin, adressant votre code ci-dessus, voir les commentaires dans le code ci-dessous:

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;
}
Créé 02/08/2011 à 08:10
source utilisateur

voix
1

Les programmeurs utilisent des concepts AVL arbres pour équilibrer les arbres binaires. Il est tout à fait simple. Plus d' informations peuvent être trouvées en ligne. Wiki rapide lien

Ci-dessous l'exemple de code qui fait l'équilibre de l'arbre en utilisant l'algorithme 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 Définition

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);
    }
};
Créé 02/08/2011 à 17:45
source utilisateur

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