简体   繁体   English

如何在AVL树中找到节点的等级?

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

I need to implement two rank queries [ rank(k) and select(r) ]. 我需要实现两个排名查询[ rank(k)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 . 据我所知, rank(k)返回给定密钥k的等级, select(r)返回给定等级r的密钥。

So my questions are: 所以我的问题是:

1.) How do you calculate the rank of a node in an AVL(self balancing BST)? 1.)如何计算AVL(自平衡BST)中节点的等级?

2.) Is it possible for more than one key to have the same rank? 2.)多个密钥是否有可能具有相同的排名? And if so, what woulud select(r) return? 如果是这样,那么select(r)返回的是什么?

I'm going to include a sample AVL tree which you can refer to if it helps answer the question. 我将包括一个示例AVL树,如果它有助于回答问题,您可以参考它。

在此输入图像描述

Thanks! 谢谢!

Your question really boils down to: "how is the term 'rank' normally defined with respect to an AVL tree?" 你的问题实际上归结为:“关于AVL树,通常如何定义术语'等级'?” (and, possibly, how is 'select' normally defined as well). (也许,'select'通常如何定义)。

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. 至少正如我所看到的那样,“rank”表示树中节点之间的位置 - 即,左边有多少个节点。 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); 两个注意事项:首先,由于这些都根本不会修改树,因此使用什么形式的平衡(例如,AVL与红/黑)没有实际区别; 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. Rank是Left子树中的节点数加1,并且是针对每个节点计算的。 I believe rank is not a concept specific to AVL trees - it can be calculated for any binary tree. 我认为rank不是AVL树特有的概念 - 它可以为任何二叉树计算。

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. 这是我编写的代码,适用于AVL Tree以获得特定值的排名。 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. [NB]如果你想从0开始你的等级,那么初始化变量rank = 0。 you definitely should have implemented the method countNodes() to execute this code. 你绝对应该实现方法countNodes()来执行这段代码。

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). 在我的程序中,元素的等级被定义为1+(没有大于该元素的元素)。 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. 1.在树结构中,跟踪包含根的子树中的元素的数量。 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. 2.将元素与节点进行比较,如果它小于节点,那么(右子元素中有1个元素)元素大于关键元素。将它添加到总数并递归搜索元素离开了孩子。

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) 3.如果元素大于根节点,那么只需在右子节点中递归搜索元素。(不需要添加任何内容,因为我们忽略了左边的树,其中所有元素都小于给定的键)

4.Terminate the algo when you find the element are reached null. 4.当您发现元素已达到null时,终止算法。

The given program returns no of elements greater than the given key. 给定程序不返回大于给定键的元素。 1+ the returned value is the rank. 1+返回的值是等级。

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 :) 希望这可以帮助 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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