Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.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++_Algorithm_Data Structures_Tree_Avl Tree - Fatal编程技术网

C++ 如何在没有父指针的情况下实现AVL树的插入?

C++ 如何在没有父指针的情况下实现AVL树的插入?,c++,algorithm,data-structures,tree,avl-tree,C++,Algorithm,Data Structures,Tree,Avl Tree,我看到了一些关于AVL的rebalance()函数实现的文章。 每次插入后,我们都应该检查插入节点的祖先节点是否平衡。 所以我认为,为了检查祖先的平衡,我了解了插入节点的父节点 但是,我想知道有没有其他方法可以不用使用父指针来实现这一点? e、 例如,节点结构: struct Node { int data; struct Node *lchild, *rchild; //*parent; }; 在遍历树时,可以维护当前节点的堆栈 stack<Node*> node

我看到了一些关于AVL的
rebalance()
函数实现的文章。
每次插入后,我们都应该检查插入节点的祖先节点是否平衡。
所以我认为,为了检查祖先的平衡,我了解了插入节点的父节点

但是,我想知道有没有其他方法可以不用使用父指针来实现这一点?
e、 例如,节点结构:

struct Node {
    int data;
    struct Node *lchild, *rchild; //*parent;
};

在遍历树时,可以维护当前节点的堆栈

stack<Node*> nodeStack;
创建子对象时,请按以下方式执行:

node.children = new Node[2]; or node.children = malloc(sizeof(Node) * 2);
node.children[0].parent = node;
node.children[1].parent = node;
使用双指针(或对C++所要求的指针的引用)应该完全消除对父指针的需要

typedef struct Node {
    int value;
    int height;
    struct Node *left;
    struct Node *right;
} Node;

int height(Node *node) {
    return (node == NULL) ? -1 : node->height;
}

void insert(Node * & node, int value) {
    if (node == NULL) {
        node = new Node();
        node->value = value;
    } else if (value < node->value) {
        insert(node->left, value);
        if (height(node->left) - height(node->right) == 2) {
            if (value < note->left->value) {
                singleRotateWithLeftChild(node);
            } else {
                doubleRotateWithLeftChild(node);
            }
        }
    } else if (value > node->value) {
        // Symmetric case
    }

    node->height = 1 + max(height(node->left), height(node->right));
}
typedef结构节点{
int值;
内部高度;
结构节点*左;
结构节点*右;
}节点;
整数高度(节点*节点){
返回(node==NULL)?-1:节点->高度;
}
无效插入(节点*&节点,int值){
if(node==NULL){
node=新节点();
节点->值=值;
}else if(值<节点->值){
插入(节点->左,值);
如果(高度(节点->左侧)-高度(节点->右侧)==2){
如果(值<注释->左->值){
singleRotateWithLeftChild(节点);
}否则{
doubleRotateWithLeftChild(节点);
}
}
}else if(值>节点->值){
//对称情况
}
节点->高度=1+最大值(高度(节点->左侧)、高度(节点->右侧));
}

如果我正确地记住了我的数据结构作业:

您要做的是将节点本身中的平衡因子存储为int,即:

  • -1:节点的左子树比右子树高一级(左重)
  • 0节点处于平衡状态;或
  • 1右子树较高(右重)
插入(节点子树)函数返回一个布尔值,如果插入使子树的高度增加,则该值为真。当从递归insert()调用返回时,更新平衡因子并重新平衡树

这可能最好用几个例子来解释:

如果当前节点处于平衡因子-1,则插入到右侧的子树中,并且插入(rchild)返回true,则您:

  • 将当前节点的平衡因子更新为0-插入前左子树较高,右子树的高度增加,因此现在它们的高度相同;及
  • 返回false-较浅树的高度增加,因此当前节点的高度保持不变

  • 如果插入到子树中,并且插入(…)返回false

  • 当前节点的平衡因子保持不变-子树高度与之前相同,平衡也相同
  • 返回false-子树高度没有更改,因此当前节点高度也没有更改

  • 如果当前节点的平衡因子为0,则插入到左侧的子树中,插入(lchild)返回true

  • 平衡因子更改为-1-插入之前子树的高度相同,插入使左侧子树的高度更高
  • 返回真值
  • (类似地,如果插入到右侧子树中,平衡因子将更改为1。)


    如果当前节点的平衡因子为-1,则插入到左侧的子树中,插入(lchild)返回true


    平衡因子将更改为-2,这意味着您必须通过执行适当的旋转来重新平衡节点。我承认,我对四次旋转对平衡因子的影响以及insert(current)将返回的内容都是空白,希望前面的示例能够充分解释跟踪节点平衡的方法。

    我的编码方式是,当您在树中搜索要删除的元素时,临时将您遍历的子链接(左或右)更改为已遍历节点堆栈中的链接(实际上是临时父指针)。然后从堆栈中弹出每个节点,恢复子指针,然后重新平衡

    <>对于C++编码,请参见./p>中的删除成员函数(当前行882) 对于C编码,请参阅中的宏调用L__;(remove)生成其名称的函数

    我认为有一个父指针对插入没有任何用处


    如果要删除由节点指针而不是唯一键标识的节点,那么我认为使用父指针可能会更快。

    由于这个问题没有完整的实现,我决定添加一个。这可以通过使用递归的
    insert
    返回当前节点来完成。下面是代码:

    typedef struct Node {
        int value;
        int height;
        struct Node *left;
        struct Node *right;
    } Node;
    
    int height(Node *node) {
        return (node == NULL) ? -1 : node->height;
    }
    
    void insert(Node * & node, int value) {
        if (node == NULL) {
            node = new Node();
            node->value = value;
        } else if (value < node->value) {
            insert(node->left, value);
            if (height(node->left) - height(node->right) == 2) {
                if (value < note->left->value) {
                    singleRotateWithLeftChild(node);
                } else {
                    doubleRotateWithLeftChild(node);
                }
            }
        } else if (value > node->value) {
            // Symmetric case
        }
    
        node->height = 1 + max(height(node->left), height(node->right));
    }
    
    typedef struct node
    {
        int val;
        struct node* left;
        struct node* right;
        int ht;
    } node;
    
    int height(node* current) {
        return current == nullptr ? -1 : current->ht;
    }
    
    int balanceFactor(node* root) {
        int leftHeight = height(root->left);
        int rightHeight = height(root->right);
    
        return leftHeight - rightHeight;
    }
    
    int calcHeight(node* n) {
        int leftHeight = height(n->left);
        int rightHeight = height(n->right);
    
        return max(leftHeight, rightHeight) + 1;
    }
    
    node* insert(node * root,int val) {
        /**
        First, recusively insert the item into the tree
        */
        if (root == nullptr) {
            root = new node();
            root->val = val;
        } else if (root->val < val) {
            root->right = insert(root->right, val);
            //the height can increase only because of the right node
            root->ht = std::max(root->ht, root->right->ht + 1);
        } else {
            root->left = insert(root->left, val);
            //the height can increase only because of the left node
            root->ht = std::max(root->ht, root->left->ht + 1);
        }
    
        //after insertion on this depth is complete check if rebalancing is required
    
        // the right subtree must be rebalanced
        if (balanceFactor(root) == -2) {
            node* r = root->right;
            node* rl = r->left;
            // it's a right right case
            if (balanceFactor(r) == -1) {
                r->left = root;
                root->right = rl;
                root->ht = calcHeight(root);
                r->ht = calcHeight(r);
                //return new root
                return r;
            } else { // it's a right left case
                node* rlr = rl->right;
                node* rll = rl->left;
                rl->left = root;
                root->right = rll;
                rl->right = r;
                r->left = rlr;
    
                root->ht = calcHeight(root);
                r->ht = calcHeight(r);
                rl->ht = calcHeight(rl);
                return rl;
            }
        } else if (balanceFactor(root) == 2) {
            node* l = root->left;
            node* lr = l->right;
            // it's a left left case
            if (balanceFactor(l) == 1) {
                l->right = root;
                root->left = lr;
                root->ht = calcHeight(root);
                l->ht = calcHeight(l);
    
                //return new root
                return l;
            } else { // it's a left right case
                node* lrl = lr->left;
                node* lrr = lr->right;
                lr->right = root;
                lr->left = l;
                root->left = lrr;
                l->right = lrl;
    
                root->ht = calcHeight(root);
                l->ht = calcHeight(l);
                lr->ht = calcHeight(lr);
    
                return lr;
            }
        }
    
        return root;
    }
    
    typedef结构节点
    {
    int-val;
    结构节点*左;
    结构节点*右;
    int-ht;
    }节点;
    整数高度(节点*当前){
    返回电流==nullptr?-1:电流->电流;
    }
    整数平衡因子(节点*根){
    int leftHeight=高度(根->左);
    int rightHeight=高度(根->右);
    返回leftHeight-rightHeight;
    }
    int calcHeight(节点*n){
    int leftHeight=高度(n->left);
    int rightHeight=高度(n->right);
    返回最大值(leftHeight,rightHeight)+1;
    }
    节点*插入(节点*根,int val){
    /**
    首先,重复地将项目插入到树中
    */
    if(root==nullptr){
    根=新节点();
    根->val=val;
    }else if(root->valright=插入(root->right,val);
    //高度只能因右侧节点而增加
    root->ht=std::max(root->ht,root->right->ht+1);
    }否则{
    根->左=插入(根->左,val);
    //高度可以用英寸表示