財神娛樂首存即享優惠回饋唷~詳情請進👉

【數據布局日本柏青哥】AVL樹

一、AVL樹簡介

????? AVL樹實質上仍是一棵二叉搜刮樹,又稱高度均衡的二叉搜刮樹。它能堅持二叉樹的高度均衡,盡可能下降二叉樹的高度,淘汰樹的均勻搜刮長度。關于二叉搜刮樹的先容以及完成,可查望自己上一篇博客。

2、AVL樹的特色

1)自身起首是一棵二叉搜刮樹。?

2)帶有均衡前提:每個結點的擺布子樹的高度之差的盡對值(均衡因子)至多為1。

3)樹中的每個左子樹以及右子樹都是AVL樹。

4)每個結點都有一個均衡因子,任一結點的均衡因子是-1,1.

注:結點的均衡因子 = 右子樹高度 – 左子樹高度

三、AVL樹的效率

一棵AVL樹有N個結點,其高度可以堅持在lgN,拔出/刪除/查找的時間龐大度也是lgN。

AVL樹的龐大水平真是比二叉搜刮樹高了整整一個數目級――它的道理并不難搞懂,但要把它用代碼完成進去還真的有點費頭腦。上面咱們來望望AVL樹完成的接口,經由過程三叉鏈進行結點的完成。

template<class?K,?class?V>
struct?AVLTreeNode//三叉鏈
{
?AVLTreeNode<K,?V>*?_left;
?AVLTreeNode<K,?V>*?_right;
?AVLTreeNode<K,?V>*?_parent;
?K?_key;
?V?_value;
?int?_bf;//右子樹與左子樹的高度差
?AVLTreeNode(const?K&?key?=?K(),?const?V&?value?=?V())//加上K()以及V(),可缺省組織
??:_left(NULL)
??,?_right(NULL)
??,?_parent(NULL)
??,?_key(key)
??,?_value(value)
??,?_bf(0)
?{}
};
template<class?K,?class?V>
class?AVLTree
{
?typedef?AVLTreeNode<K,?V>?Node;
public:
?AVLTree()
??:_root(NULL)
?{}
?void?Insert(const?K&?key,?const?V&?value);
?Node*?Find(const?K&?key);
?int?Height();
?bool?IsBalance();
?void?PrintAVLTree();
private:
?Node*?_Find(Node*?root,?const?K&?key);
?void?_RotateL(Node*&?parent);
?void?_RotateR(Node*&?parent);
?void?_RotateLR(Node*&?parent);
?void?_RotateRL(Node*&?parent);
?int?_Height(Node*?root);
?bool?_IsBalance(Node*?root);
?void?_PrintAVLTree(Node*?root);
protected:
?Node*?_root;
};

上面對拔出進行元素的闡發:

1)判定樹是否為空,為空時,新建根結點。

2)查找拔出的key是否存在,存在就退出函數,不存在就履行3)。

3)找到拔出key的地位,然后拔出結點cur。

4)更新均衡因子:從cur最先向上其父結點進行更新均衡因子,若是結點的均衡因子不知足AVL樹,進行扭轉調電競運彩抽獎節均衡因子。

template<class?K,class?V>
voi線上麻將賭博d?AVLTree<K,V>::Insert(const?K&?key,?const?V&?value)
{
?if?(_root?==?NULL)
?{
??_root?=?new?Node(key,?value);
??return;
?}
?if?(Find(key))//存在key
?{
??return;
?}
?Node*?prev?=?NULL;
?Node*?cur?=?_root;
?while?(cur)//拔出key的地位cur
?{
??if?(key?<?cur->_key)
??{
???prev?=?cur;
???cur?=?cur->_left;
??}
??else?if?(key?>?cur->_key)
??{
???prev?=?cur;
???cur?=?cur->_right;
??}
?}
?cur?=?new?Node(key,?value);//插如結點cur
?if?(prev->_key?>?key)
?{
??prev->_left?=?cur;
??cur->_parent?=?prev;
?}
?else?if?(prev->_key?<?key)
?{
??prev->_right?=?cur;
??cur->_parent?=?prev;
?}
?//prev為cur的上一個結點,即為cur是prev的父親結點
?prev?=?cur;
?cur?=?prev->_parent;
?while?(偏財運占卜cur)
?{
??//更新均衡因子:從插如的cur最先向上更新均衡因子
??cur->_bf增加偏財運的方法?=?_Height(cur->_right)?-?_Height(cur->_left);
??if?(cur->_bf?!=?-1?&&?cur->_bf?!=?1?&&?cur->_bf?!=?0)//不知足AVL樹的結點,進行扭轉調節均衡因子
??{//均衡因子為2時,肯定存在右子樹;均衡因子為-2時,肯定存在左子樹
????//左單旋:2?1(均衡因子)
????if?(cur->_bf?==?2?&&?cur->_right->_bf?==?1)
????{
?????_RotateL(cur);//引用傳遞
????}
????//右單旋:-2?-1
????else?if?(cur->_bf?==?-2?&&?cur->_left->_bf?==?-1)
????{
?????_RotateR(cur);
????}
????//擺布扭轉:-2?1
????else?if?(cur->_bf?==?-2?&&?cur->_left->_bf?==?1)
????{
?????_RotateLR(cur);
????}
????//右左扭轉六合彩版路:2?-1
????else?if?(cur->_bf?==?2?&&?cur->_right->_bf?==?-1)
????{
?????_RotateRL(cur);
????}
??}
??prev?=?cur;
??cur?=?cur->_parent;
?}
}

進行扭轉調節均衡因子,分四種環境:

(1)左單旋:cur的均衡因子為2,cur->_right的均衡因子為1。

(2)右單旋:cur的均衡因子為-2,cur->_left的均衡因子為-1。

(3)擺布扭轉:cur的均衡因子為-2,cur->_left的均衡因子為1。

(4)右左扭轉:cur的均衡因子為-2,cur->_right的均衡因子為-1。

擺布扭轉以及右左扭轉可經由過程挪用左單旋以及右單旋進行,注重收場后重置均衡因子。

若是不是很清晰,可以本人繪圖進行闡發。

【免責聲明】本站內容轉載自互聯網,其相關談吐僅代表作者小我私家概念盡非權勢巨子,不代表本站態度。如您發明內容存在版權成績,請提交相關鏈接至郵箱:,咱們將實時予以處置。