AVL平衡二叉树总结

我个人是通过b站学习的懂得

b站视频连接:

https://www.bilibili.com/video/av37955102?from=search&seid=14638889623357631324

https://www.bilibili.com/video/av37955178?from=search&seid=14638889623357631324

https://www.bilibili.com/video/av37955231?from=search&seid=14638889623357631324

旋转原则:

下面看一张图:

《AVL平衡二叉树总结》

PS:   以下 p 是A  q是B 

LL型:

1) 定义一个结构体指针指向A的左子树 ,tree *q = p->l   

2) 让A左子树连上B的右子树 p->l = q->r  (因为B是A的左子树,  所以B上所有子节点的data 都小于A 的data) ,

3) 由于A的data大于B的data ,再将B的右子树连上A   q->r = p

3) 计算q的(B)右子树p深度  p->height = max(height(p->l), height(p->r)) + 1;   // +1 是加上p本身

4) 计算q的深度   q->height = max(height(q->l), p->height) + 1;   // +1 是加上q本身

RR型:

1) 定义一个结构体指针指向A的右子树 ,tree *q = p->r

2) 让A右子树连上B的左子树 p->l = q->r  (因为B是A的右子树,  所以B上所有子节点的data 都大于A 的data) ,

3) 由于A的data小于B的data ,再将B的左子树连上A   q->l = p

3) 计算q的(B)左子树p深度  p->height = max(height(p->l), height(p->r)) + 1;    // +1 是加上p本身

4) 计算q的深度   q->height = max(height(q->l), p->height) + 1;   // +1 是加上q本身

LR型:

一次RR 一次LL

RL型:

一次LL 一次RR

下面是一个例题:

数据结构实验之查找二:平衡二叉树

Time Limit: 400 ms Memory Limit: 65536 KiB

Submit Statistic

Problem Description

根据给定的输入序列建立一棵平衡二叉树,求出建立的平衡二叉树的树根。

Input

输入一组测试数据。数据的第1行给出一个正整数N(n <= 20),N表示输入序列的元素个数;第2行给出N个正整数,按数据给定顺序建立平衡二叉树。

Output

输出平衡二叉树的树根。

Sample Input

5
88 70 61 96 120

Sample Output

70

Hint

 

Source

xam

ACcode:

#include <bits/stdc++.h>
using namespace std;
struct tree
{
    int data; //记录关键字数值
    tree *l, *r;
    int height; //平衡因子
};
int height(tree *p) //求树的深度
{
    if (p == NULL)
        return -1;
    return p->height;
}
tree *LL(tree *p) //对LL型直接在不平衡结点进行左旋转
{
    tree *q;
    q = p->l;                                        // q是p的左子树
    p->l = q->r;                                     // q的左子树一定小于p->data  所以p->l连上q->r
    q->r = p;                                        // q->r连上p
    p->height = max(height(p->l), height(p->r)) + 1; // 结点的位置变了,要更新结点的高度值
    q->height = max(height(q->l), p->height) + 1;
    return q;
}
tree *RR(tree *p) //对RR型直接在不平衡结点进行右旋转
{
    tree *q; // 连接原理与LL相同
    q = p->r;
    p->r = q->l;
    q->l = p;
    p->height = max(height(p->l), height(p->r)) + 1;
    q->height = max(height(q->r), p->height) + 1;
    return q;
}
tree *LR(tree *p)
{
    p->l = RR(p->l); //在不平衡结点p的左儿子处进行右旋转
    return LL(p);    //在不平衡结点p处进行左旋转并返回新的根
}
tree *RL(tree *p)
{
    p->r = LL(p->r); //在不平衡结点p的右儿子处进行左旋转
    return RR(p);    //在不平衡结点p处进行左旋转并返回新的根
}
tree *insert(tree *p, int k)
{
    if (p == NULL) //待插入的值赋给新开辟的结点
    {
        p = new tree;
        p->data = k;
        p->height = 0;
        p->l = p->r = NULL;
    }
    else if (k < p->data) //若待插入的值小于p的关键字数值,则插入到左子树中
    {
        p->l = insert(p->l, k);
        if (height(p->l) - height(p->r) == 2) //该树出现不平衡
        {
            if (k < p->l->data) //若待插入的值插到了左儿子的左子树上则单旋转
                p = LL(p);
            else //反之,双旋转
                p = LR(p);
        }
    }
    else if (k > p->data) //道理同上
    {
        p->r = insert(p->r, k);
        if (height(p->l) - height(p->r) == -2)
        {
            if (k > p->r->data)
                p = RR(p);
            else
                p = RL(p);
        }
    }
    p->height = max(height(p->l), height(p->r)) + 1;
    return p;
}
int main()
{
    int n, k;
    while (cin >> n)
    {
        tree *head = NULL;
        for (int i = 0; i < n; i++)
        {
            cin >> k;
            head = insert(head, k);
        }
        cout << head->data << endl;
    }
    return 0;
}

/***************************************************
User name: QXQZX
Result: Accepted
Take time: 0ms
Take Memory: 236KB
Submit time: 2018-12-19 14:58:13
****************************************************/

 

    原文作者:_且行且珍惜
    原文地址: https://www.cnblogs.com/iQXQZX/p/10258785.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞