大话数据结构学习笔记(11)C++实现二叉平衡树

#include<iostream>
using namespace std;
#define LH +1   //左高
#define EH 0	//等高
#define RH -1   //右高

class BiTNode
{
public:
	int data=0;
	int bf=0;				//结点的平衡因子
	BiTNode *lchild = NULL, *rchild=NULL;
};

class Bitree
{
private:
	bool taller;				//taller反应树高是否变化
	void R_Rotate(BiTNode *&p);   //右旋操作
	void L_Rotate(BiTNode *&p);	 //左旋操作
	void LeftBalance(BiTNode *&T);//左平衡旋转处理
	void RightBalance(BiTNode *&T);//右平衡旋转处理
public:
	BiTNode *root;
	bool InsertAVL(BiTNode *&T, int e);		  //插入结点
	Bitree() :root(NULL), taller(false){}
	~Bitree(){}
};

void Bitree::R_Rotate(BiTNode *&p)
{
	BiTNode *L;
	L = p->lchild;				//p为最小不平衡子树的根结点 L指向p的左子树的根结点
	p->lchild = L->rchild;      //L的右子树挂接到p的右子树上
	L->rchild = p;
	p = L;						//L变为新的根结点
}

void Bitree::L_Rotate(BiTNode *&p) 	    //左旋操作
{
	BiTNode *R;
	R = p->rchild;				
	p->rchild = R->lchild;      
	R->lchild = p;
	p = R;
}

//对以指针T所指结点为根的二叉树作左平衡旋转处理
//本算法结束时,指针T指向新的根结点
void Bitree::LeftBalance(BiTNode *&T)
{
	BiTNode *L, *Lr;
	L = T->lchild;		//L指向T的左子树根结点
	switch (L->bf)
	{
		//检查T的左子树的平衡度,并作相应平衡处理
	case LH://新结点插入在T的左孩子的左子树上,要作单右选处理
		T->bf = L->bf = EH;
		R_Rotate(T);
		break;
	case RH://新结点插入在T的左孩子的右子树上,要作双旋处理
		Lr = L->rchild;
		switch (Lr->bf)//修改T及其左孩子的平衡因子
		{
		case LH:
			T->bf = RH;
			L->bf = EH;
			break;
		case EH:
			T->bf = L->bf = EH;
			break;
		case RH:
			T->bf = EH;
			L->bf = LH;
			break;
		}
		Lr->bf = EH;
		L_Rotate(T->lchild);    //对T的左子树作左旋平衡处理
		R_Rotate(T);			//对T作右旋平衡处理
	}
}

void Bitree::RightBalance(BiTNode *&T)
{
	BiTNode *R, *Rl;
	R = T->rchild;		
	switch (R->bf)
	{
	case RH:
		T->bf = R->bf = EH;
		L_Rotate(T);
		break;
	case LH:
		Rl = R->lchild;
		switch (Rl->bf)
		{
		case RH:
			T->bf = LH;
			R->bf = EH;
			break;
		case EH:
			T->bf = R->bf = EH;
			break;
		case LH:
			T->bf = EH;
			R->bf = RH;
			break;
		}
		Rl->bf = EH;
		R_Rotate(T->rchild);    
		L_Rotate(T);			
	}
}

bool Bitree::InsertAVL(BiTNode *&T,int e)
{
	if (!T)
	{
		//插入新结点,树长高,taller为true
		T = new BiTNode;
		T->data = e;
		T->lchild = NULL;
		T->rchild = NULL;
		T->bf = EH;
		taller = true;
	}
	else
	{
		if (e == T->data)
		{
			//树中已经存在该结点,不再插入
			taller = false;
			return false;
		}
		if (e < T->data)
		{
			//在T的左子树往下搜索
			if (!InsertAVL(T->lchild, e))
				return false;
			if (taller)  //已经插入到左子树中
			{
				switch (T->bf)
				{
				case LH://原来左子树比右子树高,需要作左平衡处理
					LeftBalance(T);
					taller = false;
					break;
				case EH://原本左右子树等高,现在因为左子树增高而树增高
					T->bf = LH;
					taller = true;
					break;
				case RH://原本右子树比左子树等高,现在右子树等高
					T->bf = EH;
					taller = false;
					break;
				}
			}
		}
		else
		{
			//在T的右子树中继续搜索
			if (!InsertAVL(T->rchild, e))
				return false;
			if (taller) 
			{
				switch (T->bf)
				{
				case LH:
					T->bf = EH;
					taller = false;
					break;
				case EH:
					T->bf = RH;
					taller = true;
					break;
				case RH:
					RightBalance(T);
					taller = false;
					break;
				}
			}
		}
	}
	return true;
}
void main()
{
	Bitree t;
	t.InsertAVL(t.root, 3);
	t.InsertAVL(t.root, 2);
	t.InsertAVL(t.root, 1);
	t.InsertAVL(t.root, 4);
	t.InsertAVL(t.root, 5);
	t.InsertAVL(t.root, 6);
	t.InsertAVL(t.root, 7);
	t.InsertAVL(t.root, 10);
	t.InsertAVL(t.root, 9);
	t.InsertAVL(t.root, 8);
	system("pause");
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值