二叉平衡树

二叉平衡树概念

二叉平衡树首先是一棵二叉排序树
若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
左、右子树也分别为二叉排序树;
左右子树的高度差不超过一

二叉平衡树分类

跟据数据所处的位置分为:
LL 、RR、RL、LR

二叉平衡树类型判断

找到失衡的根节点root
找到导致失衡的节点node
判断node在root孩子的哪一侧   (左或右)
判断node在root的哪一侧       (左或右)

将两次判断连起来

LL型处理

取中间节点,将它的父亲作为自己的右孩子
自己的左孩子不变

自己的右孩子连到父亲的左孩子上
思考:
	自己的右孩子肯定小于父亲节点,这是由二叉排序树的性质所决定的

伪代码:
node、root:
node->rchild = root
root->lchild = node->rchild

RR型处理

取中间节点,将它的父亲作为自己的左孩子
自己的右孩子不变

自己的左孩子连到父亲的右孩子上
思考:
	自己的左孩子肯定大于父亲节点,这是由二叉排序树的性质所决定的

伪代码:
node、root:
node->lchild = root
root->rchild = node->lchild

LR型处理

(左即是小于,右即是大于)

思考:
node、root

L ====> root的孩子肯定小于root
R ====> node 肯定小于root,大于root的孩子
root->lchild < node < root

取node作为根节点
将node 的爷爷即root 作为自己的右节点
将node 的父亲作为自己的左节点

node的左孩子肯定小于node,大于node 的父亲,所以放到其父亲的右孩子上
node的右孩子肯定大于node 但小于node的爷爷,所以方法其爷爷的左孩子上

RL型处理

思考:
node、root

R ====> node 的爸爸大于node的爷爷
L ====> node肯定下于其爸爸,大于其爷爷

root < node < root->rchild

取node作为根节点
将node 的爷爷作为左节点
将node 的爸爸作为右节点

node的左孩子肯定小于node,大于node 的爷爷,所以放到其爷爷的右孩子上
node的右孩子肯定大于node 但小于node的爸爸,所以方法其爸爸的左孩子上

代码实现(更新中 。。。)

#include <stdio.h>
#include <stdlib.h>

typedef struct  treenode
{
    int data;
    int height;
    struct treenode *lchild;
    struct treenode *rchild;    
}TreeNode;

int getHeight(TreeNode *node){
    return node ? node ->height : 0;
}

int max(int a, int b){
    return a > b ? a:b;
}

void rrRotation(TreeNode *node, TreeNode **root){
    TreeNode *temp = node ->rchild;
    node ->rchild  = temp ->lchild;
    temp ->lchild  = node;
    node ->height  = max(getHeight(node ->lchild), getHeight(node ->rchild)) + 1;
    temp ->height  = max(getHeight(temp ->lchild), getHeight(temp ->rchild)) + 1; 
    *root = temp;
}

void llRotation(TreeNode *node, TreeNode **root){
    TreeNode *temp = node ->lchild;
    node ->lchild  = temp ->rchild;
    temp ->rchild  = node;
    node ->height  = max(getHeight(node ->lchild), getHeight(node ->rchild)) + 1;
    temp ->height  = max(getHeight(temp ->lchild), getHeight(temp ->rchild)) + 1; 
    *root = temp;
}

void avlInsert(TreeNode **T, int data){
    if (*T == NULL){
        *T = (TreeNode*)malloc(sizeof(TreeNode));
        (*T) -> data = data; 
        (*T) -> height = 0;
        (*T) -> lchild = NULL;
        (*T) -> rchild = NULL;
    }
    else if(data < (*T)->data ){
        // 左插
        avlInsert(&((*T)->lchild), data);
        int lheight = getHeight((*T) ->lchild);
        int rheight = getHeight((*T) ->rchild);

        if (lheight - rheight == 2){
            if (data < (*T) -> lchild ->data){
                // LL 调整
                llRotation(*T, T);
            }
            else{
                // LR 调整
                rrRotation((*T)->lchild, &(*T)->lchild);
                llRotation(*T, T);
            }
        }
    }
    else if(data > (*T)->data ){
        // 右插
        avlInsert(&((*T)->rchild), data);
        int lheight = getHeight((*T) ->lchild);
        int rheight = getHeight((*T) ->rchild);
        if (rheight - lheight == 2){
            if (data > (*T) -> rchild ->data){
                // RR 调整
                rrRotation(*T, T);
            }
            else{
                // RL 调整
                llRotation((*T)->rchild, &(*T)->rchild);
                rrRotation(*T, T);
            }
        }
    }

    (*T) ->height = max(getHeight((*T) ->lchild), getHeight((*T) ->rchild)) + 1;
}

void preOrder(TreeNode *T){
    if(T){
        printf("%d ", T->data);
        preOrder(T ->lchild);
        preOrder(T ->rchild);
    }
}

int main(){
    int i       = 0;
    TreeNode* T = NULL;
    // int num[5]  = {1,2,3,4,5};
    int num[5]  = {5,4,3,2,1};
    for(i; i<5; i++){
        avlInsert(&T, num[i]);
    }
    preOrder(T);
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值