查看“︁AVL树”︁的源代码
←
AVL树
跳转到导航
跳转到搜索
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
{{noteTA |G1=IT }} {{Infobox data structure |name=AVL樹 |type=[[树 (数据结构)|樹]] |invented_by=[[格奥尔吉·阿杰尔松-韦利斯基]]<br>[[葉夫根尼·蘭迪斯]] |invented_year=1962年 | |space_avg=<math>O(n)</math> |space_worst=<math>O(n)</math> |search_avg=<math>O(\log n)</math> |search_worst=<math>O(\log n)</math> |insert_avg=<math>O(\log n)</math> |insert_worst=<math>O(\log n)</math> |delete_avg=<math>O(\log n)</math> |delete_worst=<math>O(\log n)</math> }} [[File:Unbalanced binary tree.svg|thumb|250px|'''非AVL'''树的例子]] '''AVL树'''({{lang-en|AVL tree}})是[[计算机科学]]中最早被发明的[[自平衡二叉查找树]]。在AVL树中,任一节点对应的两棵子树的最大高度差为1,因此它也被称为'''高度平衡树'''。查找、插入和删除在平均和最坏情况下的[[時間複雜度]]都是 <math>O(\log{n})</math>。增加和删除元素的操作则可能需要藉由一次或多次[[树旋转]],以实现树的重新平衡。AVL树得名于它的发明者[[格奥尔吉·阿杰尔松-韦利斯基]]和[[葉夫根尼·蘭迪斯]],他们在1962年的论文《An algorithm for the organization of information》中公开了这一数据结构。 节点的'''平衡因子'''是它的左子树的高度减去它的右子树的高度(有時相反)。带有平衡因子1、0或 -1的节点被认为是平衡的。带有平衡因子 -2或2的节点被认为是不平衡的,并需要重新平衡这个树。平衡因子可以直接存储在每个节点中,或从可能存储在节点中的子树高度计算出来。 [[File:AVLtreef.svg|thumb|250px|同一个树在高度平衡之后的样子]] == 操作 == [[File:AVL Tree Example.gif|thumb|260px|此动画演示了不断将节点插入AVL树时的情况,并且演示了左旋(Left Rotation)、右旋(Right Rotation)、右左旋转(Right-Left Rotation)、左右旋转(Left-Right Rotation)以及带子树的右旋(Right Rotation with children)。]] AVL树的基本操作一般涉及运作同在不平衡的[[二叉查找树]]所运作的同样的算法。但是要进行预先或随后做一次或多次所谓的"AVL旋转"。 以下图表以四列表示四种情况,每行表示在该种情况下要进行的操作。在左左和右右的情况下,只需要进行一次旋转操作;在左右和右左的情况下,需要进行两次旋转操作。 [[File:Tree Rebalancing.png|800px|avl树旋转的图形描述。]] === 删除 === 从AVL树中删除,可以通过把要删除的节点向下旋转成一个葉子節點,接着直接移除这个叶子节点来完成。因为在旋转成葉子節點期间最多有log ''n''个节点被旋转,而每次AVL旋转耗费固定的时间,所以删除处理在整体上耗费O(log ''n'') 时间。 === 搜尋 === 可以像普通二叉查找树一样的进行,所以耗费O(log ''n'')时间,因为AVL树总是保持平衡的。不需要特殊的准备,树的结构不会由于查找而改变。(这是与[[伸展樹]]搜尋相对立的,它会因为搜尋而变更树结构。) == 实现描述 == 假設平衡因子是左子樹的高度減去右子樹的高度所得到的值,又假设由于在二叉排序树上插入节点而失去平衡的最小子树根节点的指针为a(即a是离插入点最近,且平衡因子绝对值超过1的祖先节点),则失去平衡后进行的规律可归纳为下列四种情况: #单向右旋平衡处理LL:由于在*a的左子树根节点的左子树上插入节点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行一次右旋转操作; #单向左旋平衡处理RR:由于在*a的右子树根节点的右子树上插入节点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行一次左旋转操作; #双向旋转(先左后右)平衡处理LR:由于在*a的左子树根节点的右子树上插入节点,*a的平衡因子由1增至2,致使以*a为根的子树失去平衡,则需进行两次旋转(先左旋后右旋)操作。 #双向旋转(先右后左)平衡处理RL:由于在*a的右子树根节点的左子树上插入节点,*a的平衡因子由-1变为-2,致使以*a为根的子树失去平衡,则需进行两次旋转(先右旋后左旋)操作。 在平衡的二叉排序树BBST (Balancing Binary Search Tree)上插入一个新的数据元素e的递归算法可描述如下: #若BBST为空树,则插入一个数据元素为e的新节点作为BBST的根节点,树的深度增1; #若e的关键字和BBST的根节点的关键字相等,则不进行; #若e的关键字小于BBST的根节点的关键字,而且在BBST的左子树中不存在和e有相同关键字的节点,则将e插入在BBST的左子树上,并且当插入之后的左子树深度增加(+1)时,分别就下列不同情况处理之: ##BBST的根节点的平衡因子为-1(右子树的深度大于左子树的深度):则将根节点的平衡因子更改为0,BBST的深度不变; ##BBST的根节点的平衡因子为0(左、右子树的深度相等):则将根节点的平衡因子更改为1,BBST的深度增1; ##BBST的根节点的平衡因子为1(左子树的深度大于右子树的深度):则若BBST的左子树根节点的平衡因子为1:则需进行单向右旋平衡处理,并且在右旋处理之后,将根节点和其右子树根节点的平衡因子更改为0,树的深度不变; #若e的关键字大于BBST的根节点的关键字,而且在BBST的右子树中不存在和e有相同关键字的节点,则将e插入在BBST的右子树上,并且当插入之后的右子树深度增加(+1)时,分别就不同情况处理之。 AVL树的调平(Erlang的实现) <syntaxhighlight lang="erlang" line="1"> balance(null) -> null; balance({null, _, null}=Tree) -> Tree; balance({Left, Value, Right}=Tree) -> Diff = count(Left)-count(Right), if (Diff < 2) and (Diff > -2) -> {balance(Left), Value, balance(Right)}; (Diff > 1) -> balance(rotate_right(Tree)); (Diff< -1) -> balance(rotate_left(Tree)); true -> exit('This is impossible!') end. rotate_right({Left, Value, Right}) -> merge_max(Left, {null, Value, Right}). rotate_left({Left, Value, Right}) -> merge_min(Right, {Left, Value, null}). merge_min({null, Value, Right}, Tree2) -> {Tree2, Value, Right}; merge_min({Left, _, _}, Tree2) -> merge_min(Left, Tree2). merge_max({Left , Value, null}, Tree2) -> {Left, Value, Tree2}; merge_max({_, _, Right}, Tree2) -> merge_max(Right, Tree2). </syntaxhighlight> == AVL節點數計算 == 高度為h的AVL樹,總節點數N最多<math>2^{h+1} -1</math>; 最少節點數<math>N_h</math>如以[[斐波那契數列]]可以用數學歸納法證明:<br> <math>N_h</math> = <math>F_{h+2}</math> - 1 (<math>F_{h+2}</math>是[[斐波那契数列]]的第h+2项,根据斐波那契多项式得来)。<br> 即:<br> <math>N_0</math> = 0 (表示AVL Tree高度為0的節點總數)<br> <math>N_1</math> = 1 (表示AVL Tree高度為1的節點總數)<br> <math>N_2</math> = 2 (表示AVL Tree高度為2的節點總數)<br> <math>N_h</math> = <math>N_{h-1}</math> + <math>N_{h-2}</math> + 1 (表示AVL Tree高度為h的節點總數)<br> 換句話說,當節點數為N時,高度h最多為<math>log_{\Phi} ( \sqrt{5} *(N+1)) -2 </math>。 == 参见 == *[[樹旋轉]] *[[伸展樹]] *[[紅黑樹]] *[[B樹]] == 引用 == *G. Adelson-Velskii and E.M. Landis, "An algorithm for the organization of information." ''Doklady Akademii Nauk SSSR'', 146:263–266, 1962([[俄语|Russian]]). [[英语|English]] translation by Myron J. Ricci in ''Soviet Math. Doklady'', 3:1259–1263, 1962. == 外部链接 == *[http://www.nist.gov/dads/HTML/avltree.html Description from the Dictionary of Algorithms and Data Structures]{{Wayback|url=http://www.nist.gov/dads/HTML/avltree.html |date=20050801092418 }} *[http://www.auto.tuwien.ac.at/~blieb/woop/avl.html AVL Tree Traversal]{{Wayback|url=http://www.auto.tuwien.ac.at/~blieb/woop/avl.html |date=20050626075425 }} *[https://web.archive.org/web/20050410150229/http://www.elude.ca/aapl/doc/classAvliTree.html Linked AVL tree] *[https://web.archive.org/web/20060110102932/http://geocities.com/wkaras/gen_cpp/avl_tree.html C++ AVL Tree Template] and [https://web.archive.org/web/20050221060634/http://geocities.com/wkaras/gen_c/cavl_tree.html C AVL TREE "Generic Package"] by Walt Karas *[http://vbwm.com/art_2001/avltree08/ A Visual Basic AVL Tree Container Class]{{Wayback|url=http://vbwm.com/art_2001/avltree08/ |date=20050818142747 }} by Jim Harris *[http://cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html AVL Trees: Tutorial and C++ Implementation]{{Wayback|url=http://cmcrossroads.com/bradapp/ftp/src/libs/C++/AvlTrees.html |date=20050714083519 }} by Brad Appleton *[http://www.mathematik.uni-ulm.de/oberon/0.5/lib/man/AVLTrees.html Ulm's Oberon Library: AVLTrees]{{Wayback|url=http://www.mathematik.uni-ulm.de/oberon/0.5/lib/man/AVLTrees.html |date=20050909145117 }} *[https://web.archive.org/web/20051120135525/http://www-old.physik.fu-berlin.de/edv_docu/documentation/xemacs-21.1.4/elib_toc.html#SEC21 The AVL TREE Data Type] *[http://www.comnets.rwth-aachen.de/doc/cncl/classCNAVLTree.html CNAVLTree Class Reference]{{Dead link|date=2019年11月 |bot=InternetArchiveBot |fix-attempted=yes }} *[http://www.stanford.edu/~blp/avl/ GNU libavl]{{Wayback|url=http://www.stanford.edu/~blp/avl/ |date=20050818080523 }} *[https://web.archive.org/web/20051101013055/http://home.earthlink.net/~akonshin/delphi_components.htm AVL-trees - balanced binary trees] by Alex Konshin *[https://web.archive.org/web/20051101013400/http://www.informatik.uni-mannheim.de/~cjk/publications/ed-media98/node11.html Simulation of AVL Trees] *[http://www.csi.uottawa.ca/~stan/csi2514/applets/avl/BT.html AVL tree applet]{{Wayback|url=http://www.csi.uottawa.ca/~stan/csi2514/applets/avl/BT.html |date=20060213024133 }} *[https://web.archive.org/web/20050801080205/http://webpages.ull.es/users/jriera/Docencia/AVL/AVL%20tree%20applet.htm Simulation of AVL Trees (DYNAMIC)] *[https://web.archive.org/web/20050801080205/http://webpages.ull.es/users/jriera/Docencia/AVL/AVL%20tree%20applet.htm AVL, Splay and Red/Black Applet] *[http://users.cis.fiu.edu/~weiss/dsaa_c2e/files.html Data Structures and Algorithm Analysis in C (2nd edition)] {{Wayback|url=http://users.cis.fiu.edu/~weiss/dsaa_c2e/files.html |date=20201109001448 }} {{计算机科学中的树}} [[Category:数据结构]] [[Category:树结构]] [[Category:二叉树]] [[Category:搜索树]] [[Category:带有伪代码示例的条目]]
该页面使用的模板:
Template:Dead link
(
查看源代码
)
Template:Infobox data structure
(
查看源代码
)
Template:Lang-en
(
查看源代码
)
Template:NoteTA
(
查看源代码
)
Template:Wayback
(
查看源代码
)
Template:计算机科学中的树
(
查看源代码
)
返回
AVL树
。
导航菜单
个人工具
登录
命名空间
页面
讨论
不转换
查看
阅读
查看源代码
查看历史
更多
搜索
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
工具
链入页面
相关更改
页面信息