平衡二叉树(Self-balancing Binary Search Tree)

Date: 2019-04-11 18:49:18

AVL树的基本操作

  1 //存储结构
  2 struct node
  3 {
  4     int data;
  5     int height; //记录当前子树的高度(叶子->根)
  6                 //存储平衡因子的话,无法通过其子树算得该树的平衡因子
  7     node *lchild, *rchild;
  8 };
  9 
 10 
 11 //新建结点
 12 node *newNode(int v)
 13 {
 14     node *root = new node;
 15     root->data = v;
 16     root->height = 1;
 17     root->lchild = root->rchild = NULL;
 18     return root;
 19 }
 20 
 21 //获取当前结点所在高度
 22 int GetHeight(node *root)
 23 {
 24     if(root == NULL)
 25         return 0;
 26     return root->height;
 27 }
 28 
 29 //计算结点的平衡因子
 30 int GetBalanceFactors(node *root)
 31 {
 32     return GetHeight(root->lchild)-GetHeight(root->rchild);
 33 }
 34 
 35 //更新结点高度
 36 void UpdataHeight(node *root)
 37 {
 38     root->height = max(GetHeight(root->lchild), GetHeight(root->rchild))+1;
 39 }
 40 
 41 //查找
 42 void Search(node *root, int x)
 43 {
 44     if(root == NULL)
 45         return;
 46     if(x == root->data)
 47         //visit
 48     else if(x < root->data)
 49         Search(root->lchild, x);
 50     else
 51         Search(root->rchild, x);
 52 }
 53 
 54 //左右旋互为逆操作
 55 //左旋
 56 void LeftRotation(node *&root)
 57 {
 58     node *temp = root->lchild;      //temp指向新的根结点B
 59     root->rchild = temp->lchild;    //B的左子树给A的右子树
 60     temp->lchild = root;            //B的左子树变为A
 61     UpdataHeight(root);             //更新结点高度
 62     UpdataHeight(temp);
 63     root = temp;                    //令B成为新的根结点
 64 }
 65 
 66 //右旋
 67 void RightRotation(node *&root)
 68 {
 69     node *temp = root->lchild;
 70     root->lchild = temp->rchild;
 71     temp->rchild = root;
 72     UpdataHeight(root);
 73     UpdataHeight(temp);
 74     root = temp;
 75 }
 76 
 77 /*
 78 1.LL: A==+2, A->lchild=+1
 79     A作为root进行右旋
 80 2.LR: A==+2, A->lchild=-1
 81     A->lchild作为root进行左旋 --> 转化为LL
 82     A作为root进行右旋
 83 3.RR: A==-2, A->rchild=-1
 84     A作为root进行左旋
 85 4.RL: A==-2, A->rchild=+1
 86     A->rchild作为root进行右旋 --> 转化为RR
 87     A作为root进行左旋
 88 */
 89 
 90 //插入
 91 void Insert(node *&root, int v)
 92 {
 93     if(root == NULL)
 94     {
 95         root = newNode(v);
 96         return;
 97     }
 98     if(v < root->data)
 99     {
100         Insert(root->lchild, v);
101         UpdataHeight(root);     //更新树高
102         if(GetBalanceFactor(root) == 2)
103         {
104             if(GetBalanceFactor(root->lchild) == 1)
105                 RightRotation(root);
106             else
107             {
108                 LeftRotation(root->lchild);
109                 RightRotation(root);
110             }
111         }
112     }
113     else
114     {
115         Insert(root->rchild, v);
116         UpdataHeight(root);
117         if(GetBalanceFactor(root) == -2)
118         {
119             if(GetBalanceFactor(root->rchild) == -1)
120                 LeftRotation(root);
121             else
122             {
123                 RightRotation(root->rchild);
124                 LeftRotation(root);
125             }
126         }
127     }
128 }
129 
130 //建立
131 node *Create(int data[], int n)
132 {
133     node *root = NULL;
134     for(int i=0; i<n; i++)
135         Insert(root, data[i]);
136     return root;
137 }

 

判断一棵树是否为AVL树

 1 #include <cstdio>
 2 const int M = 10;
 3 int pre[M]={50,38,30,45,40,48,70,60,75,80};
 4 int in[M]={30,38,40,45,48,50,60,70,75,80};
 5 struct node
 6 {
 7     int data;
 8     node *lchild, *rchild;
 9 };
10 
11 node *Create(int preL, int preR, int inL, int inR)
12 {
13     if(preL > preR)
14         return NULL;
15     node *root = new node;
16     root->data = pre[preL];
17     int k;
18     for(k=inL; k<=inR; k++)
19         if(in[k] == root->data)
20             break;
21     int numLeft = k-inL;
22     root->lchild = Create(preL+1, preL+numLeft, inL, k-1);
23     root->rchild = Create(preL+numLeft+1, preR, k+1, inR);
24 }
25 
26 int IsAvl = true;
27 int IsAVL(node *root)
28 {
29     if(root == NULL)
30         return -1;
31     int bl = IsAVL(root->lchild)+1;
32     int br = IsAVL(root->rchild)+1;
33     if(bl-br>1 || bl-br<-1)
34         IsAvl = false;
35     return bl>br?bl:br;
36 }
37 
38 int main()
39 {
40 #ifdef    ONLINE_JUDGE
41 #else
42     freopen("Test.txt", "r", stdin);
43 #endif
44 
45     node *root = Create(0,M-1,0,M-1);
46     IsAVL(root);
47     if(IsAvl)
48         printf("Yes.");
49     else
50         printf("No.");
51 
52     return 0;
53 }

 

转载于:https://www.cnblogs.com/blue-lin/p/10970187.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值