Vyvažování String založené Binární vyhledávací strom (pro kontrolu pravopisu)

hlasů
1

Aktualizace: I can not get vyvažování do práce, protože jsem nemůže dostat doAVLBalance rozpoznat funkce člena isBalanced (), isRightHeavy (), isLeftHeavy. A já nevím proč! Zkoušel jsem šerpa je příklad (třetí odpověď) přesně, ale jsem si „zpomalení je neslučitelný“ a já jsem nemohl opravit, že ... Tak jsem se snažil dělat to můj způsob ... a to mi říká, že ty členské funkce nemusí existovat, pokud jasně dělat.

„Chyba: třída‚IntBinaryTree:.. TreeNode‘nemá žádný člen‚isRightHeavy‘Jsem přilepená po vyzkoušení za poslední 4 hodiny :( Aktualizováno kód níže, pomoc by ocenili !!

Jsem vytvořit řetězec založený Binární vyhledávací strom a je třeba, aby to „Balanced“ strom. Jak to mám udělat? * Nápověda, prosím !! Díky předem!

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
};
Položena 02/08/2011 v 05:00
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
1

Existuje mnoho způsobů, jak toho dosáhnout, ale já bych naznačují, že ve skutečnosti není to tak všechno. Chcete-li uložit BST řetězců, tam jsou mnohem lepší možnosti:

  1. Použijte prewritten binární třídu vyhledávání strom. C ++ std :: set třída nabízí stejné časové záruky vyváženého binárního vyhledávacího stromu a je často prováděna jako takový. Je to podstatně jednodušší než válcování si vlastní BST.

  2. Použijte trie místo. Struktura trie dat je jednodušší a účinnější než BST řetězců, nevyžaduje žádné vyvažování vůbec, a je rychlejší než BST.

Pokud opravdu musíte napsat svůj vlastní vyvážený BST, máte mnoho možností. Většina implementací BST, které používají balancing jsou mimořádně složité a není pro lidi se slabým srdcem. Já bych navrhnout, kterým se provádí buď treap nebo splay strom, což jsou dvě vyvážené BST struktury, které jsou poměrně snadno proveditelný. Oba jsou složitější než kódu máte výše, a nemohu v tomto krátkém zajistit implementaci, ale Wikipedia hledání těchto struktur by vám měl poskytnout dostatek rad o tom, jak postupovat.

Snad to pomůže!

Odpovězeno 02/08/2011 v 06:21
zdroj uživatelem

hlasů
1

Bohužel, my programátoři jsou doslovné zvěř.

aby to „Balanced“ strom.

„Balanced“ je závislá na kontextu. Třídy úvodní datové struktury typicky se vztahují ke stromu jsou „vyvážený“, když se minimalizuje rozdíl mezi uzlu největší hloubky a uzlu nejméně hloubky. Nicméně, jak již bylo uvedeno sirem Templatetypedef, rozevírá strom je považován za vyvážení strom. To proto, že může vyvažovat stromy poměrně dobře v případě, že jen málo uzly přistupovat společně najednou často. Důvodem je, že to trvá méně uzlů traversals dostat na data v splay strom než konvenční binárního stromu v těchto případech . Na druhé straně je jeho nejhorší výkon na přístupu podle přístupu základ může být stejně zlé jako propojeného seznamu.

Když už mluvíme o spojových seznamů ...

Protože jinak bez „vyvažování“ Je to stejné jako propojený-seznamu I číst a maří účel.

To může být tak špatné, ale pro randomizované vložek není. Pokud vložíte již seřazená data, většina implementací binární vyhledávací strom ukládání dat jako nafouklý a objednal propojeny seznam. Nicméně, je to jen proto, že stavíte na jedné straně stromu nepřetržitě. (Představte si, že vkládání 1, 2, 3, 4, 5, 6, 7, atd ... do binárního stromu. Zkuste to na papíře, a uvidíme, co se stane.)

Máte-li, aby se vyrovnávala teoretickou nejhorší-must-zaručené smysl, doporučuji při pohledu jsem červeno-černém stromy. (Google to, druhý odkaz je docela dobrý.)

Máte-li ji vyvážit rozumným způsobem v tomto konkrétním případě, já bych šel s celočíselnými indexy a slušné hashovací funkce - tímto způsobem vyvažování se stane pravděpodobnostně bez dalšího kódu. To znamená, aby vaše srovnání funkce vypadat hash (strA) <hash (strB) místo toho, co jste se dostal. (Pro rychlé, ale účinné hash pro tento případ, podívejte se FNV hash. První hit na Googlu. Přejděte dolů, až uvidíte užitečné kód.) Můžete starat o podrobnosti účinnosti realizace, chcete-li. (Například, nemusíte provádět jak hash pokaždé budete porovnávat, protože jeden z řetězců nikdy nemění.)

Pokud se můžete dostat pryč s ním, doporučuji druhé, pokud jste v tísni za čas a chtějí něco rychle. V opačném případě, červeno-černé stromy jsou užitečné, protože jsou velmi užitečné v praxi, kdy je třeba vrátit své vlastní výškově vyvážené binární stromy.

A konečně, adresování výše uvedený kód, viz komentář v následující kód:

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;
}
Odpovězeno 02/08/2011 v 08:10
zdroj uživatelem

hlasů
1

Programátoři používají AVL strom koncepce vyvážit binární stromy. Je to docela jednoduché. Více informací lze nalézt na internetu. Quick wiki link

Níže je ukázkový kód, který dělá strom rovnováhu pomocí AVL algoritmus.

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);
    }
};
Odpovězeno 02/08/2011 v 17:45
zdroj uživatelem

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