简体   繁体   中英

How to find the rank of a node in an AVL tree?

I need to implement two rank queries [ rank(k) and select(r) ]. But before I can start on this, I need to figure out how the two functions work.

As far as I know, rank(k) returns the rank of a given key k , and select(r) returns the key of a given rank r .

So my questions are:

1.) How do you calculate the rank of a node in an AVL(self balancing BST)?

2.) Is it possible for more than one key to have the same rank? And if so, what woulud select(r) return?

I'm going to include a sample AVL tree which you can refer to if it helps answer the question.

在此输入图像描述

Thanks!

Your question really boils down to: "how is the term 'rank' normally defined with respect to an AVL tree?" (and, possibly, how is 'select' normally defined as well).

At least as I've seen the term used, "rank" means the position among the nodes in the tree -- ie, how many nodes are to its left. You're typically given a pointer to a node (or perhaps a key value) and you need to count the number of nodes to its left.

"Select" is basically the opposite -- you're given a particular rank, and need to retrieve a pointer to the specified node (or the key for that node).

Two notes: First, since neither of these modifies the tree at all, it makes no real difference what form of balancing is used (eg, AVL vs. red/black); for that matter a tree with no balancing at all is equivalent as well. Second, if you need to do this frequently, you can improve speed considerably by adding an extra field to each node recording how many nodes are to its left.

Rank is the number of nodes in the Left sub tree plus one, and is calculated for every node. I believe rank is not a concept specific to AVL trees - it can be calculated for any binary tree.

Select is just opposite to rank. A rank is given and you have to return a node matching that rank.

The following code will perform rank calculation:

void InitRank(struct TreeNode *Node)
{
        if(!Node)
        {
                return;
        }
        else
        {       Node->rank = 1 + NumeberofNodeInTree(Node->LChild);
                InitRank(Node->LChild);
                InitRank(Node->RChild);
        }

}


int NumeberofNodeInTree(struct TreeNode *Node)
{
        if(!Node)
        {
                return 0;
        }
        else
        {
                  return(1+NumeberofNodeInTree(Node->LChild)+NumeberofNodeInTree(Node->RChild));
        }
}

Here is the code i wrote and worked fine for AVL Tree to get the rank of a particular value. difference is just you used a node as parameter and i used a key a parameter. you can modify this as your own way. Sample code:

    public int rank(int data){
    return rank(data,root);
}

private int rank(int data, AVLNode r){
    int rank=1;
    while(r != null){
        if(data<r.data)
            r = r.left;
        else if(data > r.data){
            rank += 1+ countNodes(r.left);
            r = r.right;
        }
        else{
            r.rank=rank+countNodes(r.left);
            return r.rank;
        }
    }
    return 0;
}

[NB] If you want to start your rank from 0 then initialize variable rank=0. you definitely should have implemented the method countNodes() to execute this code.

Here is what I have done. In my program the rank of an element is defined as the 1+(no of elements greater than that element). You can note here that the element need not present in the tree.

Algorithm to find rank:

1.In the tree structure keep track of the no of elements in a sub tree including the root. So the head of the tree will contains total elements in the tree.

2.Compare the element with a node,if it is smaller than the node, then there are (1+no.of elements in right child) elements greater than the key element.Add it to the total and recursively search the element in the left child.

3.If the element is greater than the root node then just search the element recursively in the right child.(no need to add anything since we are neglecting the left tree, in which all the elements are less than the given key)

4.Terminate the algo when you find the element are reached null.

The given program returns no of elements greater than the given key. 1+ the returned value is the rank.

code snippet:

int AVLUtils::rank(Node *root,long long val)
  {
    int n_ele_greater=0;
    int rank =0;

    if(root == NULL)
    return 0;
   if(val < root->key)
     {
    n_ele_greater = 1+this->n_elements(root->right_child)+this->rank(root->left_child,val);
     }
   else if(val > root->key)
     {
    n_ele_greater=this->rank(root->right_child,val);
    }

    else if(val == root->key)
    {
    return(this->n_elements(root->right_child));
    }
    return(n_ele_greater);
   }

Hope this helps :)

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