二叉平衡树AVL

对于二叉查找树,由于不良数据,可能形成很不平衡的树。而且,在删除操作的时候,总是在右子树中寻找节点来代替删除节点,

这样有助于左子树比右子树深,查找时间增加。虽然可以随机选取左子树的最大节点或右子树的最小节点来替代删除节点,来消除不平衡性。

但通过这种做法来消除不平衡并没有被证实。

所以,二叉平衡树应运而生。




.h

struct Node
{
	int data;
	int height;
	Node *left;
	Node *right;
};


class AVL
{
	public:
		AVL();
		~AVL();
	
		void  Insert(int data);
		void  Delete(int data);
		Node *Find(int data);
		Node *FindMin();
		Node *FindMax();
		void  Print();
		
	private:
		Node* _Insert(Node* root, int data);
		Node* _SingleToRight(Node *K2);
		Node* _SingleToLeft(Node *K2);
		Node* _DoubleToLeftRight(Node *K3);
		Node* _DoubleToRightLeft(Node *K3);
		int   _Height(Node *root);
		int   _Max(int a, int b);
		void  _Print(Node *root);
		void  _MakeEmpty(Node *root);
		Node *_Find(Node *root, int data);
		Node *_Delete(Node *root, int data);
		Node *_FindMin(Node *root);
		Node *_FindMax(Node *root);
		int   _GetBalanceFactor(Node *root);
		
		Node *_root;
};

.cpp

AVL::AVL()
{
	_root = NULL;
}

AVL::~AVL()
{
	_MakeEmpty(_root);
}

void AVL::_MakeEmpty(Node *root)
{
	if(root != NULL)
	{
		_MakeEmpty(root->left);
		_MakeEmpty(root->right);
		delete root;
	}
}
void AVL::Insert(int data)
{
	_root = _Insert(_root, data);
}

Node *AVL::_Insert(Node *root, int data)
{
	if(root == NULL)
	{
		root         = new Node;
		root->left   = root->right = NULL;
		root->data   = data;
		root->height = 0;
	}
	else if(data > root->data) //Right
	{
		root->right = _Insert(root->right, data);
		if( (_Height(root->right) - _Height(root->left)) == 2)
		{
			if(data > root->right->data)  //Right
			{
				root = _SingleToLeft(root);
			}
			else                          //Left
			{
				root = _DoubleToRightLeft(root);
			}
		} 
	}
	else if(data < root->data)   //Left
	{
		root->left = _Insert(root->left, data);
		if( (_Height(root->left) - _Height(root->right)) == 2)
		{
			if(data < root->left->data)  //Left
			{
				root = _SingleToRight(root);
			}
			else                         //Right
			{
				root = _DoubleToLeftRight(root);
			}
		}
	}
	root->height = _Max(_Height(root->left), _Height(root->right)) + 1;
	return root;
} 

int AVL::_Max(int a, int b)
{
	if(a > b)
		return a;
	else
		return b;
}	

Node *AVL::_SingleToRight(Node *K2)
{
	Node *K1 = K2->left;
	K2->left = K1->right;
	K1->right = K2;
	
	K1->height = _Max(_Height(K1->left),_Height(K1->right) ) + 1;
	K2->height = _Max(_Height(K2->left),_Height(K2->right) ) + 1;
	
	return K1;
}

		
Node *AVL::_SingleToLeft(Node *K2)
{
	Node *K1 = K2->right;
	K2->right = K1->left;
	K1->left  = K2;
	
	K1->height = _Max(_Height(K1->left),_Height(K1->right) ) + 1;
	K2->height = _Max(_Height(K2->left),_Height(K2->right) ) + 1;
	
	return K1;
}

Node *AVL::_DoubleToLeftRight(Node *K3)
{
	K3->left = _SingleToLeft(K3->left);
	Node* K1 = _SingleToRight(K3);
	return K1;
}

Node *AVL::_DoubleToRightLeft(Node *K3)
{
	K3->right = _SingleToRight(K3->right);
	Node *K1 = _SingleToLeft(K3);
	return K1;
}

int AVL::_Height(Node *root)
{
	if(root == NULL)
		return -1;
	else
		return root->height;
}

void AVL::Print()
{
	_Print(_root);
	cout << endl;
}

void  AVL::_Print(Node *root)
{
	if(root != NULL)
	{
		_Print(root->left);
		cout << root->data << " ";
		_Print(root->right);
	}
}


Node *AVL::Find(int data)
{
	return _Find(_root, data);
}

Node *AVL::FindMin()
{
	return _FindMin(_root);
}

Node *AVL::_FindMin(Node *root)
{
	if(root == NULL)
		return NULL;
	
	if(root->left == NULL)
		return root;
	else 
		return _FindMin(root->left);
}

Node *AVL::_FindMax(Node *root)
{
	if(root == NULL)
		return NULL;
	
	if(root->right == NULL)
		return root;
	else
		return _FindMax(root->right);
}

Node *AVL::_Find(Node *root, int data)
{
	if(root == NULL)
		return NULL;
	if(data > root->data)
	{
		return _Find(root->right, data);
	}
	else if(data < root->data)
	{
		return _Find(root->left, data);
	}
	return root;
}

void AVL::Delete(int data)
{
	_root = _Delete(_root, data);
}

Node *AVL::_Delete(Node *root, int data)
{
	if(root == NULL)
		return NULL;
	
	if(data > root->data)
	{
		root->right = _Delete(root->right, data);
	}
	else if(data < root->data)
	{
		root->left  = _Delete(root->left, data);
	}
	else
	{
		if(root->left != NULL && root->right != NULL)
		{
			Node *tmp = _FindMin(root->right);
			root->data = tmp->data;
			root->right = _Delete(root->right, tmp->data);
		}
		else
		{
			Node *del = root;
			if(root->left == NULL)
				root = root->right;
			else if(root->right == NULL)
				root = root->left;
			delete del;	
		}
	}
	
	if( root == NULL)
		return root;
		
	root->height = _Max(_Height(root->left), _Height(root->right)) + 1;
	
        //删除,可以等效为插入失去平衡
        //唯一不同的是,需要从删除结点一直比较到根,检查是否平衡
        if( _GetBalanceFactor(root) == 2 ) // left
	{
		if( _GetBalanceFactor(root->left) >= 0)
		{
			return _SingleToRight(root);
		}
		else
		{
			return _DoubleToLeftRight(root);
		}
	}
	else if(_GetBalanceFactor(root) == -2) //right
	{
		if( _GetBalanceFactor(root->right) <= 0)
		{
			return _SingleToLeft(root);
		}
		else
		{
			return _DoubleToRightLeft(root);
		} 
	}
	
	return root;
}


int AVL::_GetBalanceFactor(Node *root)
{
	return _Height(root->left) - _Height(root->right);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值