平衡二叉树

平衡二叉树 (Balanced Binary Tree) (AVL树) :
空树,或者任一结点左、右子树高度差的绝对值不超过1

设 n h 高 度 为 h 的 平 衡 二 叉 树 的 最 少 结 点 数 。 结 点 数 最 少 时 : n h = n h − 1 + n h − 2 + 1 设n_h高度为h的平衡二叉树的最少结点数。结点数最少时: n_h = n_{h-1} + n_{h-2} + 1 nhhnh=nh1+nh2+1

typedef struct avl_tree* tree;
struct avl_tree{
    tree left;	//指向左子树
    tree right;	//指向右子树
    elementtype data;	//结点数据
    int height;	//树高
};
int max(int a, int b)
{
	return a > b ? a : b;
}

tree left_rotation(tree a){	//左单旋
/* 注意:a必须有一个左子结点b */
/* 将a与b做左单旋,更新a与b的高度,返回新的根结点b */
    tree b=a->left;
    a->left=b->right;
    b->right=a;
    a->height=max(a->left->height,a->right->height)+1;
    b->height=max(b->left->height,b->right->height)+1;
    return b;
}

tree right_rotation(tree a){	//右单旋
    /* 把left,right对换即可 */
    tree b=a->right;
    a->right=b->left;
    b->left=a;
    a->height=max(a->left->height,a->right->height)+1;
    b->height=max(b->left->height,b->right->height)+1;
    return b;
}

tree left_right_rotation(tree a){	//左-右双旋
/* 注意:a必须有一个左子结点b,且b必须有一个右子结点c */
/* 将a、b与c做两次单旋,返回新的根结点c */
    
    a->left=right_rotation(a->left);	//将B与C做右单旋,C被返回
    return left_rotation(a);	//将A与C做左单旋,C被返回
}

tree right_left_rotation(tree a){	//右-左双旋
    /* 同理,把left,right对换即可 */
    a->right=left_rotation(a->right);
    return right_rotation(a);
}

/* 如果不使用递归,将会使程序变得非常复杂,比如:
插入时需要判断在left还是right,插入后还需要判断是否仍是平衡二叉树,
而判断又需求树高,除此之外,还需要记录“麻烦节点”和“发现者”,因此下面采用递归实现:*/
tree insert(elementtype x,tree bt){
    if (!bt){	//若插入空树,则新建包含一个结点的树
        bt=(tree)malloc(sizeof(struct avl_tree));
        bt->height=0;
        bt->left=bt->right=NULL;
        bt->data=x;
        return bt;	//插入空树结束
    }
    else if (x < bt->data){
        bt->left=insert(x,bt->left);	//插入bt的左子树
        if (bt->left->height - bt->right->height == 2){	//如果需要左旋
            if (x < bt->left->data) bt=left_rotation(bt);	//左单旋
            else bt=bt->left_right_rotation(bt);	//左-右双旋
        }
    }
    else if (x > bt->data){	//插入bt的右子树
		bt->right=insert(bt->right);
		if (bt->right->height - bt->left->height == 2){	//如果需要右旋
            if (x > bt->right->data) bt=right_rotation(bt);	//右单旋
			else bt=right_left_rotation(T);	//右-左双旋
        }
	}
	//else x==bt->data,无须操作
    
	bt->height=max(bt->left,bt->right)+1;	//更新树高

	return bt;
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值