Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 平衡AVL树(C+;+;)_C++_Algorithm_Data Structures_Binary Tree_Avl Tree - Fatal编程技术网

C++ 平衡AVL树(C+;+;)

C++ 平衡AVL树(C+;+;),c++,algorithm,data-structures,binary-tree,avl-tree,C++,Algorithm,Data Structures,Binary Tree,Avl Tree,我正在努力找出如何为我的班级平衡AVL树。我把它插进了这个: Node* Tree::insert(int d) { cout << "base insert\t" << d << endl; if (head == NULL) return (head = new Node(d)); else return insert(head, d); } Node* Tree::insert(Node*&

我正在努力找出如何为我的班级平衡AVL树。我把它插进了这个:

Node* Tree::insert(int d)
{
    cout << "base insert\t" << d << endl;
    if (head == NULL)
        return (head = new Node(d));
    else
        return insert(head, d);
}

Node* Tree::insert(Node*& current, int d)
{
    cout << "insert\t" << d << endl;
    if (current == NULL)
        current = new Node(d);
    else if (d < current->data) {
        insert(current->lchild, d);
        if (height(current->lchild) - height(current->rchild)) {
            if (d < current->lchild->getData())
                rotateLeftOnce(current);
            else
                rotateLeftTwice(current);
        }
    }
    else if (d > current->getData()) {
        insert(current->rchild, d);
        if (height(current->rchild) - height(current->lchild)) {
            if (d > current->rchild->getData())
                rotateRightOnce(current);
            else
                rotateRightTwice(current);
        }
    }

    return current;
}
Node*Tree::insert(int d)
{
cout getData())
旋转一次(电流);
其他的
旋转两次(电流);
}
}
如果(d>当前->获取数据()){
插入(当前->归档文件,d);
if(高度(当前->存档)-高度(当前->存档)){
如果(d>current->rchild->getData())
旋转一次(电流);
其他的
旋转两次(电流);
}
}
回流;
}

我的计划是让对balance()的调用检查树是否需要平衡,然后根据需要进行平衡。问题是,我甚至不知道如何遍历树来找到正确的不平衡节点。我知道如何递归遍历树,但我似乎无法将该算法转换为查找最低不平衡节点。我在编写迭代算法时也遇到了困难。任何帮助都将不胜感激。:)

您可以在给定点测量分支的高度,以计算不平衡量

(请记住,高度差>=2表示您的树不平衡)

根据不平整度,您可以根据需要旋转

void Tree::rotateLeftOnce(TreeNode*& node){
     TreeNode *otherNode;

     otherNode = node->left;
     node->left = otherNode->right;
     otherNode->right = node;
     node = otherNode;
}


void Tree::rotateLeftTwice(TreeNode*& node){
     rotateRightOnce(node->left);
     rotateLeftOnce(node);
}


void Tree::rotateRightOnce(TreeNode*& node){
     TreeNode *otherNode;

     otherNode = node->right;
     node->right = otherNode->left;
     otherNode->left = node;
     node = otherNode;
}


void Tree::rotateRightTwice(TreeNode*& node){
     rotateLeftOnce(node->right);
     rotateRightOnce(node);
}
现在我们知道了如何旋转,假设您想在树中插入一个值。。。首先,我们检查树是否为空

TreeNode* Tree::insert(int d){
     if(isEmpty()){
         return (root = new TreeNode(d));  //Is empty when root = null
     }
     else
         return insert(root, d);           //step-into the tree and place "d"
}
当树不为空时,我们使用递归遍历树并到达需要的位置

TreeNode* Tree::insert(TreeNode*& node, int d_IN){
     if(node == NULL)  // (1) If we are at the end of the tree place the value
         node = new TreeNode(d_IN);
     else if(d_IN < node->d_stored){  //(2) otherwise go left if smaller
         insert(node->left, d_IN);    
         if(Height(node->left) - Height(node->right) == 2){
            if(d_IN < node->left->d_stored)
                rotateLeftOnce(node);
            else
                rotateLeftTwice(node);
         }
     }
     else if(d_IN > node->d_stored){ // (3) otherwise go right if bigger
        insert(node->right, d_IN);
        if(Height(node->right) - Height(node->left) == 2){
            if(d_IN > node->right->d_stored)
                rotateRightOnce(node);
            else
                rotateRightTwice(node);
        }
     }
     return node;
}
应该成为

if (height(current->lchild) - height(current->rchild) == 2) { ...

if (height(current->rchild) - height(current->lchild) == 2) {...

一些资源

  • 等等,等等,等等。 你不是每次插入东西都要检查每个分支的“高度”吧

    测量高度意味着横穿所有分支。平均值-每次插入到这样的树中都将花费O(N)。如果是,你需要这样一棵树做什么?您也可以使用排序数组:它提供O(N)插入/删除和O(logn)搜索


    正确的AVL处理算法必须存储每个节点的左/右高度差。然后,在每次操作(插入/删除)之后,您必须确保没有任何受影响的节点过于不平衡。要做到这一点,你需要进行所谓的“旋转”。在测试过程中,你不会重新测量高度。您不必这样做:每次旋转都会以某种可预测的值改变受影响节点的平衡。

    转到,所有常见的操作(如添加、删除)都会执行,加上concat和split

    注释掉的是代码右上旋转和左下旋转,下面是我的右下旋转和我的左下旋转。我认为上面的逻辑是相反的:

     void rotateRight(Node *& n){
        //Node* temp = n->right;
        //n->right = temp->left;
        //temp->left = n;
        //n = temp;
        cout << "}}}}}}}}}}}}}}}}}}}}}ROTATE RIGHT}}}}}}}}}}}}}}}}}}}}}" << endl;
        Node *temp = n->left;
        n->left = temp->right;
        temp->right = n;
        n = temp;
    }
    
    void rotateLeft(Node *& n){
        //Node *temp = n->left;
        //n->left = temp->right;
        //temp->right = n;
        //n = temp;
        cout << "}}}}}}}}}}}}}}}}}}}}}ROTATE LEFT}}}}}}}}}}}}}}}}}}}}}" << endl;
        Node* temp = n->right;
        n->right = temp->left;
        temp->left = n;
        n = temp;
    }
    
    void rotateRight(节点*&n){
    //节点*temp=n->右侧;
    //n->右=温度->左;
    //温度->左=n;
    //n=温度;
    cout left=温度->右侧;
    温度->右=n;
    n=温度;
    }
    void rotateLeft(节点*&n){
    //节点*temp=n->左侧;
    //n->左=温度->右;
    //温度->右=n;
    //n=温度;
    cout right=temp->left;
    温度->左=n;
    n=温度;
    }
    
    顺便说一句,如果你熟悉java,
    对我来说
    Lafore的《java中的数据结构和算法》一书对我理解数据结构有很大帮助。虽然它没有AVL,但它确实广泛地讨论了红黑树,如果发现更容易的话,
    i
    。一旦您用Java理解了它们,您就可以用您熟悉的任何其他语言来完成,关键是要理解它们的方式work@Carlos:我同意,只要语言不晦涩(perl…),就可以演示算法或数据结构的实现。感谢您的详细评论。这很有帮助。但是,我认为我不理解您的插入方法。第一个参数的用途是什么?在上面显示的代码中,我从头部开始循环,直到找到树的正确位置。这是一种不好的方法吗?使用insert方法,您似乎已经知道节点所属的位置。请参阅编辑,希望它会有所帮助。循环不是最好的选择,而是使用递归,因为它更容易操作树的节点;在第二个insert方法中,是什么导致了这种情况?请将您的问题更新一下,并将您的实现更新为check@Carlos我只是不明白你在做什么:代码:“if(d_IN>node->right->d){rotateRightOnce}else{rotateRightTworth}”。你能解释一下吗。这将是一个很大的帮助。
    if (height(current->lchild) - height(current->rchild) == 2) { ...
    
    if (height(current->rchild) - height(current->lchild) == 2) {...
    
     void rotateRight(Node *& n){
        //Node* temp = n->right;
        //n->right = temp->left;
        //temp->left = n;
        //n = temp;
        cout << "}}}}}}}}}}}}}}}}}}}}}ROTATE RIGHT}}}}}}}}}}}}}}}}}}}}}" << endl;
        Node *temp = n->left;
        n->left = temp->right;
        temp->right = n;
        n = temp;
    }
    
    void rotateLeft(Node *& n){
        //Node *temp = n->left;
        //n->left = temp->right;
        //temp->right = n;
        //n = temp;
        cout << "}}}}}}}}}}}}}}}}}}}}}ROTATE LEFT}}}}}}}}}}}}}}}}}}}}}" << endl;
        Node* temp = n->right;
        n->right = temp->left;
        temp->left = n;
        n = temp;
    }