数据结构与算法分析学习笔记--第四章AVL树

/******************************************
AVL树,又叫做平衡二叉树。
定义就是,任意节点的两个子树高度差不超过1。
查找;查找最大、最小节点;等于二叉查找树相同,不同的部分主要是插入和删除部分。
插入部分:
存在四种破坏平衡的情况,1、节点左孩子的左孩子处插入新的结点。2、节点左孩子的右孩子处插入结点。3、结点的右孩子的右孩子处插入结点。4、结点的右孩子的左结点处插入结点。
其中1、3属于同一类型,2、4属于同一类型。
1、3只需要一次旋转就可以重新做到平衡,而2、4需要经过两个旋转才能重新做到平衡。
*******************************************/

#include <iostream>
using namespace std;
template<typename T>
class AVL_Node
{
public:
	AVL_Node *m_left;
	AVL_Node *m_right;
	T m_data;
	unsigned int m_hight;
public:
	//构造函数
	AVL_Node(T data = T(), AVL_Node<T> *left = NULL, AVL_Node<T> *right = NULL, unsigned int hight = 0)
		:(m_data(data), m_left(left), m_right(right), m_hight(hight)){}
	AVL_Node(AVL_Node<T> *node)
	{
		if (node)
		{
			m_data = node->m_data;
			m_left = node->m_left;
			m_right = node->m_right;
			m_hight = node->m_hight;
		}
		else
		{
			AVL_Node();
		}
	}
};
template<typename T>
class AVL_Tree
{
public:
	AVL_Node<T> *MakeEmpty(AVL_Node<T> *tree);
	AVL_Node<T> *Find(AVL_Node<T> *tree, T data);	//与二叉查找树一样
	AVL_Node<T> *FindMin(AVL_Node<T> *tree);		//与二叉查找树一样
	AVL_Node<T> *FindMax(AVL_Node<T> *tree);		//与二叉查找树一样
	AVL_Node<T> *SingleRotateWithLeft(AVL_Node<T> *tree);
	AVL_Node<T> *SingleRotateWithRight(AVL_Node<T> *tree);
	AVL_Node<T> *DoubleRotateWithLeft(AVL_Node<T> *tree);
	AVL_Node<T> *DoubleRotateWithRight(AVL_Node<T> *tree);
	AVL_Node<T> *Insert(AVL_Node<T> *tree, T data);
	AVL_Node<T> *Delete(AVL_Node<T> *tree, T data);
	int Height(AVL_Node<T> *tree);
public:
	AVL_Node<T> *m_head;
public:
	AVL_Tree(AVL_Node<T> *head = NULL) : m_head(head){}
};
template<typename T>
int AVL_Tree<T>::Height(AVL_Node<T> *tree)
{
	if (tree == NULL)
		return -1;
	return tree->m_hight;
}
template<typename T>
AVL_Node<T> *AVL_Tree<T>::Find(AVL_Node<T> *tree, T data)
{
	AVL_Node<T> *pTarget = tree
	while (pTarget)
	{
		if (pTarget->m_data < data)
			pTarget = pTarget->m_LChild;
		else if (pTarget->m_data > data)
			pTarget = pTarget->m_RChild;
		else
			return pTarget;
	}
}
//左孩子的左子树插入
//        k3    
//        /
//       k2   ------>      k2    
//       /                /  \
//      k1               k1   k3 
template<typename T>
AVL_Node<T> *AVL_Tree<T>::SingleRotateWithLeft(AVL_Node<T> *tree)
{
	AVL_Node<T> *temp = tree->m_left;
	tree->m_left = temp->m_right;
	temp->m_right = tree;

	temp->m_hight = max(Height(temp->m_left), Height(temp->m_right)) + 1;
	tree->m_hight = max(Height(tree->m_left), Height(tree->m_right)) + 1;
	return temp;
}

//右孩子的右子树插入
//        k1
//         \
//         k2    ------------>     k2
//          \                     /  \
//          k3                   k1   k3
template<typename T>
AVL_Node<T> *AVL_Tree<T>::SingleRotateWithRight(AVL_Node<T> *tree)
{
	AVL_Node<T> *temp = tree->m_right;
	tree->m_right = temp->m_left;
	temp->m_left = tree;

	temp->m_hight = max(Height(temp->m_left), Height(temp->m_right)) + 1;
	tree->m_hight = max(Height(tree->m_left), Height(tree->m_right)) + 1;
	return temp;
}

//往左孩子的右子树插入的情况
//        k3
//        /
//       k1              
//        \
//         k2
template<typename T>
AVL_Node<T> *AVL_Tree<T>::DoubleRotateWithLeft(AVL_Node<T> *tree)
{
	//先将k1和k2的顺序进行右旋转,将k1变成k2的左子树
	tree->m_left = SingleRotateWithRight(tree->m_left);
	//再将k3和k2的顺序进行左旋转,将k3变成k2的右子树
	return SingleRotateWithLeft(tree);
}

//右孩子的左子树插入
//        k1
//        \
//         k3
//         /
//        k2
template<typename T>
AVL_Node<T> *AVL_Tree<T>::DoubleRotateWithRight(AVL_Node<T> *tree)
{
	//先将k3和k2的顺序进行左旋转,将k3变成k2的右子树
	tree->m_left = SingleRotateWithLeft(tree->m_left);
	//再将k1和k2的顺序进行右旋转,将k3变成k2的左子树
	return SingleRotateWithRight(tree);
}

template<typename T>
AVL_Node<T> *AVL_Tree<T>::Insert(AVL_Node<T> *tree, T data)
{
	if (tree == NULL)
	{
		tree = new AVL_Node();
		if (tree == NULL)
			cout << "out of space!" << ;
		else
		{
			tree->m_data = data;
			tree->m_hight = 0;
		}
	}
	else if (data < tree->m_data)
	{
		tree->m_left = Insert(tree->m_left, data);
		if ((Height(tree->m_left) - Height(tree->m_right)) == 2)
		{
			if (data < tree->m_left->m_data)
				tree = SingleRotateWithLeft(tree);
			else
				tree = DoubleRotateWithLeft(tree);
		}
	}
	else if (data > tree->m_data)
	{
		tree->m_right = Insert(tree->m_right, data);
		if ((Height(tree->m_right) - Height(tree->m_left)) == 2)
		{
			if (data < tree->m_left->m_data)
				tree = SingleRotateWithRight(tree);
			else
				tree = DoubleRotateWithRight(tree);
		}
	}
	tree->m_hight = max(Height(tree->m_left), Height(tree->m_right)) + 1;
	return tree;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值