[英]How to find the rank of a node in an AVL tree?
我需要實現兩個排名查詢[ rank(k)
和select(r)
]。 但在我開始之前,我需要弄清楚這兩個功能是如何工作的。
據我所知, rank(k)
返回給定密鑰k
的等級, select(r)
返回給定等級r
的密鑰。
所以我的問題是:
1.)如何計算AVL(自平衡BST)中節點的等級?
2.)多個密鑰是否有可能具有相同的排名? 如果是這樣,那么select(r)
返回的是什么?
我將包括一個示例AVL樹,如果它有助於回答問題,您可以參考它。
謝謝!
你的問題實際上歸結為:“關於AVL樹,通常如何定義術語'等級'?” (也許,'select'通常如何定義)。
至少正如我所看到的那樣,“rank”表示樹中節點之間的位置 - 即,左邊有多少個節點。 您通常會獲得指向節點的指針(或者可能是鍵值),您需要計算其左側的節點數。
“選擇”基本上相反 - 您獲得了特定的排名,並且需要檢索指向指定節點(或該節點的密鑰)的指針。
兩個注意事項:首先,由於這些都根本不會修改樹,因此使用什么形式的平衡(例如,AVL與紅/黑)沒有實際區別; 就此而言,沒有平衡的樹也是等同的。 其次,如果您需要經常這樣做,您可以通過向每個節點添加額外的字段來記錄其左側有多少節點,從而大大提高速度。
Rank是Left子樹中的節點數加1,並且是針對每個節點計算的。 我認為rank不是AVL樹特有的概念 - 它可以為任何二叉樹計算。
選擇與排名正好相反。 給出排名,您必須返回與該排名匹配的節點。
以下代碼將執行排名計算:
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));
}
}
這是我編寫的代碼,適用於AVL Tree以獲得特定值的排名。 差異只是你使用一個節點作為參數,我使用一個鍵參數。 你可以按自己的方式修改它。 示例代碼:
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]如果你想從0開始你的等級,那么初始化變量rank = 0。 你絕對應該實現方法countNodes()來執行這段代碼。
這就是我所做的。 在我的程序中,元素的等級被定義為1+(沒有大於該元素的元素)。 你可以在這里注意到元素不需要存在於樹中。
查找排名的算法:
1.在樹結構中,跟蹤包含根的子樹中的元素的數量。 因此樹的頭部將包含樹中的總元素。
2.將元素與節點進行比較,如果它小於節點,那么(右子元素中有1個元素)元素大於關鍵元素。將它添加到總數並遞歸搜索元素離開了孩子。
3.如果元素大於根節點,那么只需在右子節點中遞歸搜索元素。(不需要添加任何內容,因為我們忽略了左邊的樹,其中所有元素都小於給定的鍵)
4.當您發現元素已達到null時,終止算法。
給定程序不返回大於給定鍵的元素。 1+返回的值是等級。
代碼段:
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);
}
希望這可以幫助 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.