简体   繁体   中英

Why do we return a pointer to a node instead of void function for avl tree implementation?

Okay so I seem to have gotten a bit lost. I am trying to insert data into a tree and when checking for balance and whether or not to rotate, I default to checking through the root. When I check examples online, I see that we can also rotate along other nodes in the tree as well. How do we figure out which node to use to balance the tree and how do we reach said node? I also saw that instead of having void functions to implement the insert and rotation functions, people use a node pointer return type instead. What is the purpose of that? I know the answers may be super obvious I am just lost.

struct TNode{
    int data;
    TNode* left;
    TNode* right;
};
class Tree{
public:
    TNode* root;
public:
    Tree()
    {root = nullptr;}
    int height(TNode* node);
    int balanceFactor(TNode* node);
    bool isBalance(TNode* node)
    {return balanceFactor(node)<-1 && balanceFactor(node)>1?true:false;}
    void avlInsert(int key);
    void LLRotation(TNode* node);
};
int Tree::height(TNode* node){
    int l = 0;
    int r = 0;
    if(!node->left && !node->right)
        return 0;
    if(node->left)
        l = height(node->left) + 1;
    if(node->right)
        r = height(node->right) + 1;
    return l > r ? l : r;
}
int Tree::balanceFactor(TNode *node){
    if(node->left && node->right)
        return height(node->left) - height(node->right);
    else if(node->left && !node->right)
        return height(node);
    else
        return -1 * height(node);
}
void Tree::LLRotation(TNode *node){
    TNode* nl = node->left;
    node->left = nl->right;
    nl->right = node;
    if(root == node)
        root = nl;
}
void Tree::avlInsert(int key){
    TNode* trav;
    TNode* follow;
    TNode* node = new TNode;
    node->data = key;
    node->left = nullptr;
    node->right = nullptr;
    if (!root)
        root = node;
    else{
        trav = root;
        while (trav){
            if (key < trav->data){
                follow = trav;
                trav = trav->left;
            }
            else{
                follow = trav;
                trav = trav->right;
            }
        }
        if(key < follow->data)
            follow->left = node;
        else
            follow->right = node;
    }
    if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
               LLRotation(root);
}

It really depends on your implementation some people they want to return a node, using a void function does not change the result much. For insert function you need to check only after you insert the node so you can go ahead and insert that node than rotate it. Please note that this function will only work if you have an AVL Tree to start with. Also your code is not correct, below:

if (balanceFactor(root) == 2 && balanceFactor(root->left) == 1)
               LLRotation(root);

This is not how you check it for insertion.... That's for deletion buddy, I think you are getting mixed up. Usually for insertion you check if the balanceFactor is between 1 and -1, so if you are getting 2, then it is a left heavy tree, in your case, because it is left-right, which means you should do Right rotation........ Buddy......

int l = 0;
    int r = 0;
    if(!node->left && !node->right)
        return 0;
    if(node->left)
        l = height(node->left) + 1;
    if(node->right)
        r = height(node->right) + 1;
    return l > r ? l : r;

Height function, extremely inefficient... Instead define height as a variable for node and then modify it after each insertion, deletion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM