(四)数据结构-平衡二叉树

#include "iostream"
#include "cmath"
using namespace std;

//首先分析了这几种旋转,发现都和平衡因子有关系,当一个结点平衡因子为2的时候,就该旋转了。
/*左旋之后,K1子节点的右枝上如果有结点给予K2,左枝上的结点保持不变;
  右旋之后,K1子节点的左枝上如果有结点给予K2,右枝上的结点保持不变。*/

template<class T>
class avlTree
{
public:
	avlTree();
	avlTree(const avlTree &rhs);
	~avlTree();
	const avlTree<T> &operator=(const avlTree &rhs);
	//int Balance(avlNode *t);   //隐含了一个类嵌套的问题,就是私有类的位置问题。BAB  OR  ABA 
	void insert(const T &x);
	void remove(const T &x);
	void inOrderPrint();
	
private:
	struct avlNode       
	{
		T element;
		avlNode *left;
		avlNode *right;
		int height;

		avlNode(const T &theElement, avlNode *lt, avlNode *rt, int h = 0)
			:element(theElement), left(lt), right(rt), height(h){}
	};
	avlNode *root;
	
	void RR(avlNode *k2);
	void LL(avlNode *k2);
	void LR(avlNode *k2);
	void RL(avlNode *k2);
	void insert(const T &x, avlNode * &root);   //结点比较的插入
	void remove(const T &x, avlNode * &root);
	void inOrderPrint(avlNode * root);
public:
	int height(avlNode *t);
};

template<class T>
avlTree<T>::avlTree()
{
	root = NULL;
}

template<class T>
avlTree<T>::~avlTree()
{
	
}

template<class T>
avlTree<T>::avlTree(const avlTree &rhs)
{
	root = rhs;
}

template<class T>
const avlTree<T> &avlTree<T>::operator=(const avlTree &rhs)
{
	if(this = &rhs)
		return *this;
	delete root;
	root = new avlNode;
	root = rhs.root;

	return *this;
}

/*if the tree is unbalance ,adjust the smallest unbalance tree to get the balance tree */
/* the smallest unbalance root node is the nearest to the branches nodes*/
template<class T>
int avlTree<T>::height(avlNode *t)
{
	return root == NULL ? -1 : root->height;
}
  
/*  case one RR    //定义右旋,右旋时K2的左孩子一定不为空。  //外侧插入
 *			80 ← k2                  60 
 *          /\                        /\ 
 *   k1→  60 90         →          20 80
 *         / \                       /  /\
 *        20 75                     ?  75 90
 *        /       
 *       ?                 
 */

template<class T> 
void avlTree<T>::RR(avlNode *k2)   //the t node is unbalance node 
{
	avlNode *k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;

	k2->height = max(height(k2->right), height(k2->left)) + 1;
	k1->height = max(height(k1->left), k2->height) + 1;
	k2 = k1;
}

/* case two LL     //定义左旋,左旋时,k2的右孩子一定不为空    //外侧插入
 *    k2→ 100                        120 
 *          /\                         /\ 
 *        85 120   ←k1    →        100 130 
 *           /  \                     / \   \  
 *          110 130                  85 110  ?
 *               \
 *                ?
 */
template<class T>
void avlTree<T>::LL(avlNode *k2) 
{
	avlNode *k1;   //enter the tree
	k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;

	k2->height = max(height(k2->right), height(k2->left)) + 1;
	k1->height = max(height(k2->right), k2->height) + 1;
	k2 = k1;
}

/* case three RL       //内测插入  //r有个孩子不为空
 * the detal can contain two cases
 * first
 *
 *                 LL                      RR
 *        100     →    p → 100         →        90 
 *         /\                 /\                   /\ 
 *   p → 80 120        l → 90 120               80 100 
 *        /\                 /                    /\   \ 
 *       60 90 ← r         80                  60 85 120 
 *          /               /\                     /
 *         85              60 85                  ?
 *         /                  /
 *        ?                  ?
 */  
template<class T>
void avlTree<T>::RL(avlNode *k2) 
{
	LL(k2->left);
	RR(k2);
}

/* case four LR      //内测插入  //r有个孩子不为空
 * the detal can contain two cases
 *                     右旋               左旋 
 *          80          →     80 ← p     →     85 
 *          /\                 /\                 /\ 
 *         60 100 ← p        60 85 ← r         80 100 
 *            /\                   \              /  /\ 
 *       l →85 120               100            60 90 120 
 *            \                   /\               /
 *            90                 90 120           ?
 *            /                  / 
 *           ?                  ?
 */
template<class T>
void avlTree<T>::LR(avlNode *k2)
{
	RR(k2->right);
	LL(k2);
}

//插入策略,插完调整
/*  在特殊情况时                 //特殊情况先左旋为正常情况在进行右旋。         
 *             39    <-k2    LL        39   <-k2  RR          30   <-r
 *             /                       /                      /\  
 *     k1->   20            --->  r-> 30         --->  k1->  20 39    <-k2
 *             \                      / 
 *        r->  30             k1->   20
 */    
template<class T>
void avlTree<T>::insert(const T &x)
{
	insert(x, root);
}

template<class T>
void avlTree<T>::insert(const T &x, avlNode * &root)
{
	if(root == NULL)       //如果根树为block,and then insert at there
		root = new avlNode(x, NULL, NULL);
	else if(x < root->element)   //左子树上插入
	{
		insert(x, root->left);    
		if(height(root->left) - height(root->right) == 2)
			if(x < root->left->element)   
				RR(root);
			else                  //上述特殊情况下的插入
				LR(root);
	}
	else if(x > root->element)
	{
		insert(x, root->right);
		if((height(root->right) - height(root->left)) == 2)
			if(x > root->right->element)
				LL(root);
			else
				RL(root);
	}
	else 
		;
	root->height = max(height(root->left), height(root->right)) + 1;    //旋转之后,现在找到左孩子和右孩子的高度,然后定义自己的高度
}

//删除策略,将要删的右子结点的最小节点值给了删的那个root->element
/*  在特殊情况时                         
 *             39     <-root             30            
 *             / \                       / \                     
 *            20 49           --->      20 49       
 *               /                      
 *              30                 delete:30   
 */ 

template<class T>
void avlTree<T>::remove(const T &data)   //删除结点
{
	remove(data, root);
}

template<class T>
void avlTree<T>::remove(const T &data, avlNode * &root)
{
	if(root == NULL)   //此节点不存在,
		return;
	if(data < root->element)  //左子树上进行删除
	{
		remove(data, root->left);   //循环找到那个结点
		if(height(root->right) - height(root->left) == 2)
		{
			if(root->right->left != NULL && (height(root->right->left) > height(root->right->right)))
				RL(root);
			else
				RR(root);
		}
	}
	else if(data > root->element)  //右子树上进行删除
	{
		remove(data, root->right);
		if(height(root->left) - height(root->right) == 2)
		{
			if((root->left->right) != NULL && (height(root->left->right) > height(root->left->left)))
				LR(root);
			else
				LL(root);
		}
	}
	else if(data == root->element)    //这个结点上的删除
	{
		if(root->right != NULL && root->left != NULL)   //两个子节点都存在
		{
			avlNode *temp = root->right;
			while(temp != NULL) temp = temp->left;  //将右子结点的最小值替换root
			root->element = temp->element;
			remove(root->element, root->right);    //再将那个最小的值清除
			if(height(root->left) - height(root->right) == 2)
			{
			if(root->left->right != NULL && height(root->left->right) > height(root->left->left))
				RL(root);
			else
				LL(root);
			}
		}
		else     //只存在一个子节点或不存在子节点
		{
			avlNode *temp = root;
			if(root->left == NULL)    //只有右结点,将其作为根结点
				root = root->right;
			else if(root->right == NULL)
				root = root->left;
			delete temp;
			temp = NULL;
		}
	}
	if(root == NULL) return;
	root->height = max(height(root->left), height(root->right)) + 1;  //重设高度
		return;
}

template<class T>
void avlTree<T>::inOrderPrint()    //中序遍历输出
{
	inOrderPrint(root);
}

template<class T>
void avlTree<T>::inOrderPrint(avlNode * root)  
{
	if(root == NULL)
		return;
	if(root->left)
		inOrderPrint(root->left);
	cout << root->element << " ";
	if(root->right)
		inOrderPrint(root->right);
	return;
}

int main()
{
	avlTree<int> tree;
	tree.insert(20);
	tree.insert(30);
	tree.insert(25);
	tree.remove(25);
	
	tree.inOrderPrint();

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值