AVL树的旋转与插入

  1. typedef struct AVLNode *Position;
  2. typedef Position AVLTree; /* AVL树类型 */
  3. struct AVLNode{
  4. ElementType Data; /* 结点数据 */
  5. AVLTree Left;     /* 指向左子树 */
  6. AVLTree Right;    /* 指向右子树 */
  7. int Height;       /* 树高 */
  8. };
  9. int Max ( int a, int b )
  10. {
  11. return a > b ? a : b;
  12. }
  13. AVLTree SingleLeftRotation ( AVLTree A )
  14. { /* 注意:A必须有一个左子结点B */
  15. /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
  16. AVLTree B = A->Left;
  17. A->Left = B->Right;
  18. B->Right = A;
  19. A->Height = Max( GetHeight(A->Left), GetHeight(A->Right) ) + 1;
  20. B->Height = Max( GetHeight(B->Left), A->Height ) + 1;
  21. return B;
  22. }
  23. AVLTree DoubleLeftRightRotation ( AVLTree A )
  24. { /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
  25. /* 将A、B与C做两次单旋,返回新的根结点C */
  26. /* 将B与C做右单旋,C被返回 */
  27. A->Left = SingleRightRotation(A->Left);
  28. /* 将A与C做左单旋,C被返回 */
  29. return SingleLeftRotation(A);
  30. }
  31. /*************************************/
  32. /* 对称的右单旋与右-左双旋请自己实现 */
  33. /*************************************/
  34. AVLTree Insert( AVLTree T, ElementType X )
  35. { /* 将X插入AVL树T中,并且返回调整后的AVL树 */
  36. if ( !T ) { /* 若插入空树,则新建包含一个结点的树 */
  37. T = (AVLTree)malloc(sizeof(struct AVLNode));
  38. T->Data = X;
  39. T->Height = 0;
  40. T->Left = T->Right = NULL;
  41. } /* if (插入空树) 结束 */
  42. else if ( X < T->Data ) {
  43. /* 插入T的左子树 */
  44. T->Left = Insert( T->Left, X);
  45. /* 如果需要左旋 */
  46. if ( GetHeight(T->Left)-GetHeight(T->Right) == 2 )
  47. if ( X < T->Left->Data )
  48. T = SingleLeftRotation(T);      /* 左单旋 */
  49. else
  50. T = DoubleLeftRightRotation(T); /* 左-右双旋 */
  51. } /* else if (插入左子树) 结束 */
  52. else if ( X > T->Data ) {
  53. /* 插入T的右子树 */
  54. T->Right = Insert( T->Right, X );
  55. /* 如果需要右旋 */
  56. if ( GetHeight(T->Left)-GetHeight(T->Right) == -2 )
  57. if ( X > T->Right->Data )
  58. T = SingleRightRotation(T);     /* 右单旋 */
  59. else
  60. T = DoubleRightLeftRotation(T); /* 右-左双旋 */
  61. } /* else if (插入右子树) 结束 */
  62. /* else X == T->Data,无须插入 */
  63. /* 别忘了更新树高 */
  64. T->Height = Max( GetHeight(T->Left), GetHeight(T->Right) ) + 1;
  65. return T;
  66. }

原文地址:https://www.cnblogs.com/lzdxh027/p/11336899.html

时间: 2024-11-09 07:11:14

AVL树的旋转与插入的相关文章

AVL树的旋转

平衡二叉树在进行插入操作的时候可能出现不平衡的情况,AVL树即是一种自平衡的二叉树,它通过旋转不平衡的节点来使二叉树重新保持平衡,并且查找.插入和删除操作在平均和最坏情况下时间复杂度都是O(log n) AVL树的旋转一共有四种情形,注意所有旋转情况都是围绕着使得二叉树不平衡的第一个节点展开的. 1. LL型 平衡二叉树某一节点的左孩子的左子树上插入一个新的节点,使得该节点不再平衡.这时只需要把树向右旋转一次即可,如图所示,原A的左孩子B变为父结点,A变为其右孩子,而原B的右子树变为A的左子树,

AVL树平衡旋转详解

AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, 2, 3, 4, 5, 6, 7..., n.在BST树中,比较理想的状况是每个子树的左子树和右子树的高度相等,此时搜索的时间复杂度是log(N).可是,一旦这棵树演化成了线型树的时候,这个理想的情况就不存在了,此时搜索的时间复杂度是O(N),在数据量很大的情况下,我们并不愿意看到这样的结果. 现在

数据结构--Avl树的创建,插入的递归版本和非递归版本,删除等操作

AVL树本质上还是一棵二叉搜索树,它的特点是: 1.本身首先是一棵二叉搜索树. 2.带有平衡条件:每个结点的左右子树的高度之差的绝对值最多为1(空树的高度为-1). 也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树). 对Avl树进行相关的操作最重要的是要保持Avl树的平衡条件.即对Avl树进行相关的操作后,要进行相应的旋转操作来恢复Avl树的平衡条件. 对Avl树的插入和删除都可以用递归实现,文中也给出了插入的非递归版本,关键在于要用到栈. 代码如下: #inclu

AVL树的旋转操作详解

[0]README 0.0) 本文部分idea 转自:http://blog.csdn.net/collonn/article/details/20128205 0.1) 本文仅针对性地分析AVL树的单旋转(左左单旋转和右右单旋转)和 双旋转(左右双旋转和右左单旋转)的内部核心技巧: 0.2) 不得不提的是,旋转有两个属性: 轴 和 旋转方向: (旋转轴即是原最小树经过旋转修正后的符合AVL的最小树的根节点)0.3) 旋转轴的确定 : (干货--单双旋转的旋转轴确定问题) 0.3.1)单旋转:旋

AVL树的JAVA实现及AVL树的旋转算法

1,AVL树又称平衡二叉树,它首先是一颗二叉查找树,但在二叉查找树中,某个结点的左右子树高度之差的绝对值可能会超过1,称之为不平衡.而在平衡二叉树中,任何结点的左右子树高度之差的绝对值会小于等于 1. 2,为什么需要AVL树呢?在二叉查找树中最坏情况下查找某个元素的时间复杂度为O(n),而AVL树能保证查找操作的时间复杂度总为O(logn). 3,AVL树的JAVA代码实现: AVLTree  继承 BinarySearchTree 并改写 添加节点的add方法,在add方法中判断插入元素后是否

AVL树C++实现(插入,删除,查找,清空,遍历操作)

AVL.h文件代码 #pragma once #include<iostream> #include<stack> #include <assert.h> using namespace std; using namespace std; template<class T> struct AVLNode{ T data; AVLNode<T>*left, *right; int bf; AVLNode() :left(NULL), right(N

AVL树的旋转实现

AVL树:带有平衡条件的二叉查找树,即一棵AVL树是其每个节点的左子树和右子树的高度最多相差1的二叉查找树.一般通过Single Rotate和Double Rotate来保持AVL树的平衡.AVL树的实现如下: 1) Single Rotate 2)Double Rotate 1) Single Rotate ( SingleRotateWithRight同理) static Position SingleRotateWithLeft(Position K2) { Position K1; K

AVL 树的插入、删除、旋转归纳

参考链接: http://blog.csdn.net/gabriel1026/article/details/6311339 之前简单了解过 AVL 树,知道概念但一直没动手实践过.Now AVL 树是二叉搜索树的一种.二叉搜索树的规则就是:每个节点的 left child 都比自己小,right child 都比自己大.而 AVL 的在此之上又加了一个规则:每个节点的 left 深度与 right 深度只差<=1,这样就能充分利用 二叉树的结构,避免出现一个分支走到黑,导致搜索效率变低.如下图

以AVL树为例理解二叉树的旋转(Rotate)操作

树旋转是在二叉树中的一种子树调整操作, 每一次旋转并不影响对该二叉树进行中序遍历的结果. 树旋转通常应用于需要调整树的局部平衡性的场合. 树旋转包括两个不同的方式, 分别是左旋转和右旋转. 两种旋转呈镜像, 而且互为逆操作.  平衡二叉树在进行插入操作的时候可能出现不平衡的情况,AVL树即是一种自平衡的二叉树,它通过旋转不平衡的节点来使二叉树重新保持平衡,并且查找.插入和删除操作在平均和最坏情况下时间复杂度都是O(log n)   AVL树的旋转一共有四种情形,注意所有旋转情况都是围绕着使得二叉