Equilibrio de cadena en función del árbol de búsqueda binaria (para revisión ortográfica)

votos
1

Actualización: No se puede obtener Equilibrio a trabajar, porque no puedo conseguir doAVLBalance para reconocer las funciones miembro isBalanced (), isRightHeavy (), isLeftHeavy. Y no sé por qué! Probé el ejemplo de Faja (tercera respuesta) exactamente, pero me sale desaceleración es incompatible y no podía arreglar eso ... así que traté de hacerlo a mi manera ... y me dice que no existen esas funciones miembro, cuando que claramente hacen.

Error: Clase 'IntBinaryTree:.. NodoArbol' no tiene ningún miembro 'isRightHeavy' estoy atascado después de intentarlo durante las últimas 4 horas :( código actualizado a continuación, ayuda sería muy apreciada !!

Estoy creando una cadena en función del árbol de búsqueda binaria y la necesidad de que sea un árbol equilibrado. ¿Cómo hago esto? * Ayuda por favor !! ¡Gracias por adelantado!

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
};
Publicado el 02/08/2011 a las 05:00
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
1

Hay muchas maneras de hacer esto, pero me gustaría sugerir que en realidad no lo hace como todos. Si desea almacenar un BST de cuerdas, hay mucho mejores opciones:

  1. Utilizar una clase de árbol de búsqueda binaria escrito previamente. La ++ std :: set de clase C ofrece las mismas garantías de tiempo como un árbol binario de búsqueda equilibrado y se implementa a menudo como tal. Es considerablemente más fácil de usar que rodar es el propietario BST.

  2. Utilice un trie lugar. La estructura de datos trie es más simple y más eficiente que un BST de cadenas, no requiere equilibrio en absoluto, y es más rápido que un BST.

Si realmente debe escribir su propia BST equilibrada, usted tiene muchas opciones. La mayoría de las implementaciones que utilizan el equilibrio de BST son extremadamente complejos y no son para los débiles de corazón. Me gustaría sugerir la aplicación o bien un Treap o un árbol biselado, que son dos estructuras BST equilibradas que son bastante fáciles de implementar. Son tanto más complejo que el código que tiene encima y no puedo en este corto espacio de proporcionar una implementación, pero una búsqueda de Wikipedia para estas estructuras deben darle un montón de consejos sobre cómo proceder.

¡Espero que esto ayude!

Respondida el 02/08/2011 a las 06:21
fuente por usuario

votos
1

Por desgracia, los programadores son bestias literales.

que sea un árbol "equilibrado".

"Equilibrado" depende del contexto. Las clases de estructuras de datos introductorios típicamente se refieren a un árbol de ser "equilibrado" cuando se minimiza la diferencia entre el nodo de mayor profundidad y el nodo de menos profundidad. Sin embargo, como se ha mencionado por Sir Templatetypedef, un árbol biselado se considera un árbol de equilibrado. Esto es debido a que puede equilibrar árboles bastante bien en los casos en que algunos nodos de acceso juntos al mismo tiempo con frecuencia. Esto se debe a que se necesita menos recorridos de nodos para llegar a los datos en un árbol biselado de un árbol binario convencional en estos casos . Por otra parte, su rendimiento peor de los casos sobre una base de acceso por el acceso puede ser tan malo como una lista enlazada.

Hablando de listas enlazadas ...

Porque de otra manera sin el "equilibrio" que es lo mismo que una lista enlazada que leo y en contra del propósito.

Se puede ser tan malo, pero para insertos aleatorios no lo es. Si inserta datos ya ordenados-, la mayoría de las implementaciones de árbol binario de búsqueda almacenan datos como una hinchada y ordenó lista enlazada. Sin embargo, eso es sólo porque usted está construyendo un lado del árbol de forma continua. (Imagínese la inserción de 1, 2, 3, 4, 5, 6, 7, etc ... en un árbol binario. Pruébalo en papel y ver qué pasa.)

Si usted tiene que equilibrar en un sentido teórico peor de los casos, debe garantizados por, recomiendo mirar a los árboles rojo-negro. (Google él, segundo enlace es bastante bueno.)

Si usted tiene que equilibrar de una manera razonable para este escenario particular, me gustaría ir con índices enteros y una función hash decente - de esa manera el equilibrio ocurrirá probabilísticamente sin ningún código adicional. Es decir, que su función de comparación parezca almohadilla (strA) <almohadilla (strB) en lugar de lo que tienes ahora. (Para un hash rápida pero eficaz para este caso, mira hacia arriba hash FNV. En primer golpe en Google. Ir abajo hasta que vea código útil.) Puede preocuparse por los detalles de la eficiencia de aplicación si así lo desea. (Por ejemplo, usted no tiene que realizar tanto hashes cada vez que se compara ya que una de las cuerdas nunca cambia.)

Si usted puede salirse con la suya, le recomiendo este último si estás en un crujido de tiempo y quieres algo rápido. De lo contrario, árboles rojo-negro valen la pena ya que son extremadamente útiles en la práctica cuando se necesita para rodar sus propios árboles binarios de altura balanceada.

Por último, las direcciones en el código anterior, ver los comentarios en el código de abajo:

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;
}
Respondida el 02/08/2011 a las 08:10
fuente por usuario

votos
1

Los programadores usan conceptos AVL árbol de equilibrar los árboles binarios. Es muy sencillo. Más información se puede encontrar en línea. Wiki rápida enlace

A continuación se muestra el código de ejemplo, que hace balance de árbol utilizando el algoritmo 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;
}

Definición de clase

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);
    }
};
Respondida el 02/08/2011 a las 17:45
fuente por usuario

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