平衡二叉树(AVL树)C/C++、C#代码实现

平衡二叉树是带有平衡条件的二叉查找树,指的是空树或者任一结点左、右高度差的绝对值不超过1的二叉树.
比如:
平衡二叉树(AVL树)C/C++、C#代码实现_第1张图片
实现的难点在于,二叉树的平衡旋转
分为四种旋转,RR、LL、LR、RL旋转

RR旋转

平衡二叉树(AVL树)C/C++、C#代码实现_第2张图片
麻烦结点在发现者右子树的右边,所以叫RR插入,需要RR旋转

LL旋转

平衡二叉树(AVL树)C/C++、C#代码实现_第3张图片
麻烦结点在发现者左子树的左边,所以叫LL插入,需要LL旋转

LR旋转

平衡二叉树(AVL树)C/C++、C#代码实现_第4张图片

RL旋转

平衡二叉树(AVL树)C/C++、C#代码实现_第5张图片

C/C++实现

#include //栈
#include 
#include 
#include 
using namespace std;
template <typename Comparable>
class AVLTree
{
private:
	static const int ALLOWED_IMBLANCE = 1;
	struct AVLNode
	{
		Comparable element;
		AVLNode * left;
		AVLNode * right;
		int height;

		AVLNode(const Comparable & theElement, AVLNode *lt, AVLNode *rt,int h = 0)
			:element(theElement), left(lt), right(rt),height(h) {}
		AVLNode(Comparable && theElement, AVLNode *lt, AVLNode *rt, int h = 0)
			:element(std::move(theElement)), left(lt), right(rt),height(h) {}
	};
	AVLNode * root;
	void Insert(const Comparable &x, AVLNode * & t);
	void Insert(Comparable && x, AVLNode *&t);
	void Insert(initializer_list<Comparable> &d, AVLNode *& t);
	void Remove(const Comparable &x, AVLNode *&t);
	AVLNode * findMin(AVLNode *t)const;
	AVLNode * findMax(AVLNode *t)const;
	bool contains(const Comparable &x, AVLNode *t) const;
	void makeEmpty(AVLNode * &t);
	void PrintTree(AVLNode *t) const;
	AVLNode* clone(AVLNode *t)const
	{
		if (t == nullptr)
			return nullptr;
		return new AVLNode(t->element, clone(t->left), clone(t->right));
	}
	void rotateWithLeftChild(AVLNode *& k2);
	void rotateWithRightChild(AVLNode *& k2);
	void doubleWithLeftChild(AVLNode *&k3);
	void doubleWithRightChild(AVLNode *&k3);
	void balance(AVLNode*& t);
public:
	AVLTree() :root(nullptr) {}
	AVLTree(const AVLTree & rhs) :root(nullptr) { root = clone(rhs.root); }
	AVLTree(AVLTree && rhs) :root(nullptr) {	root = rhs.root;rhs = nullptr;}
	~AVLTree() { makeEmpty(); }
	const Comparable & findMin() const { return findMin(root)->element; }
	const Comparable & findMax() const { findMax(root)->element; }
	bool contains(const Comparable & x) const { return contains(x, root); }
	bool isEmpty() const { return root == nullptr; }
	int height(AVLNode *t) const { return t == nullptr ? -1 : t->height; }
	void PrintTree()const { PrintTree(root); }
	void makeEmpty() { makeEmpty(root); }
	void Insert(const Comparable &x) { Insert(x,root); }
	void Insert(Comparable && x) { Insert(x,root); }
	void Insert(initializer_list<Comparable>d) { Insert(d, root); }
	void Remove(const Comparable &x) { Remove(x, root); }
	AVLTree & operator=(const AVLTree & rhs)
	{
		if (this != &rhs)
		{
			makeEmpty();
			root = clone(rhs.root);
		}
		return *this;
	}
	AVLTree & operator=(AVLTree && rhs)
	{
		if (this != &rhs)
		{
			makeEmpty();
			root = rhs.root;
			rhs.root = nullptr;
		}
		return *this;
	}
	friend int Max(int a, int b);

};
int Max(int a, int b)
{
	return (a > b) ? a : b;
}
template<typename Comparable>
void AVLTree<Comparable>::Insert(const Comparable & x, AVLNode *& t)
{
	if (t == nullptr)
	{
		t = new AVLNode(x, nullptr, nullptr);
	}
	else if (x < t->element)
		Insert(x, t->left);
	else if (t->element < x)
		Insert(x, t->right);

	balance(t);

}

template<typename Comparable>
void AVLTree<Comparable>::Insert(Comparable && x, AVLNode *& t)
{

	if (t == nullptr)
	{
		t = new AVLNode(std::move(x), nullptr, nullptr);
	}
	else if (x < t->element)
		Insert(std::move(x), t->left);
	else if (t->element < x)
		Insert(std::move(x), t->right);
	balance(t);
}

template<typename Comparable>
void AVLTree<Comparable>::Insert(initializer_list<Comparable> &d, AVLNode *& t)
{
	for (auto p = d.begin(); p != d.end(); p++)
	{
		Insert(*p, t);
	}
}
template<typename Comparable>
void AVLTree<Comparable>::Remove(const Comparable & x, AVLNode *& t)
{
	if (t == nullptr) //没找到相应的项什么都不做
		return;
	if (x < t->element)
		Remove(x, t->left);
	else if (x > t->element)
		Remove(x, t->right);
	else if (t->left != nullptr && t->right != nullptr)//找到了 但是有两个儿子
	{//取右子树的最小元素替代 或者左子树的最大元素,好处是右子树的最小元素一定在右子树的最左边,左子树的最大元素一定在左子树的最右边
		t->element = findMin(t->right)->element;//在右子树中找到最小的元素填充删除结点
		Remove(t->element, t->right);//在删除节点的右子树中删除最小元素.
	}
	else //有一个儿子 或者没有
	{
		AVLNode * oldNode = t;
		t = (t->left != nullptr) ? t->left : t->right; //如果有儿子,就让儿子接上,如果没有那t就设置为nullptr
		delete oldNode;
	}
	balance(t);
}

template<typename Comparable>
typename AVLTree<Comparable>::AVLNode *
AVLTree<Comparable>::findMin(AVLNode * t) const
{
	//递归版本
	//if (t == nullptr)  
	//	return nullptr;
	//if (t->left == nullptr)
	//	return t;
	//return findMin(t->left);

	//非递归版本
	if (t != nullptr)
		while (t->left != nullptr)
			t = t->right;
	return t;

}

template<typename Comparable>
typename AVLTree<Comparable>::AVLNode *
AVLTree<Comparable>::findMax(AVLNode * t)const
{
	//递归版本
	/*if (t == nullptr)
		return;
	if (t->right == nullptr)
		return t;
	return findMax(t->right);*/
	if (t != nullptr)
		while (t->right != nullptr)
			t = t->right;
	return t;


}

template<typename Comparable>
bool AVLTree<Comparable>::contains(const Comparable & x, AVLNode * t) const
{
	//递归版本
	/*if (t == nullptr)
		return false;
	else if (x < t->element)
		return contains(x, t->left);
	else if (x > t->element)
		return contains(x, t->right);
	else
		retu true;*/

		//非递归版本
	while (t != nullptr)
	{
		if (x < t->element)
			t = t->left;
		else if (x > t->element)
			t = t->right;
		else
			return true;
	}
	return false;
}

template<typename Comparable>
void AVLTree<Comparable>::makeEmpty(AVLNode *& t)
{

	if (t != nullptr)
	{
		makeEmpty(t->left);
		makeEmpty(t->right);
		delete t;
	}
	t = nullptr;

}

template<typename Comparable>
void AVLTree<Comparable>::PrintTree(AVLNode * t) const
{
	//递归先序遍历
	if (t != nullptr)
	{
		std::cout << t->element << " "; //先序遍历
		PrintTree(t->left);
		PrintTree(t->right);
	}
	//非递归的先序遍历, 使用栈
	//AVLNode * temp = t;
	//stacks;
	//while (temp || !s.empty())
	//{
	//	while (temp) //一直向左将沿途结点压入栈
	//	{
	//		s.push(temp);
	//		temp = temp->left;
	//	}
	//	if (!s.empty())
	//	{
	//		temp = s.top();
	//		s.pop();
	//		std::cout << temp->element << " "; //先序遍历
	//		temp = temp->right;
	//	}
	//}
	//层序遍历,使用队列
	//AVLNode * temp;
	//queueq;
	//if (t == nullptr)
	//	return;
	//q.push(t);
	//while (!q.empty())
	//{
	//	temp = q.front();
	//	q.pop();
	//	std::cout << temp->element << " ";
	//	if (temp->left)
	//		q.push(temp->left);
	//	if (temp->right)
	//		q.push(temp->right);
	//}


}

template<typename Comparable>
void AVLTree<Comparable>::rotateWithLeftChild(AVLNode *& k2)//左旋
{
	AVLNode *k1 = k2->left;
	k2->left = k1->right;
	k1->right = k2;
	k2->height = Max(height(k2->left), height(k2->right)) + 1;
	k1->height = Max(height(k1->left), k2->height) + 1;
	k2 = k1;//把所有的设置都变为改变后的设置
}

template<typename Comparable>
void AVLTree<Comparable>::rotateWithRightChild(AVLNode *& k2)//右旋
{
	AVLNode *k1 = k2->right;
	k2->right = k1->left;
	k1->left = k2;
	k2->height = Max(height(k2->right), height(k2->left)) + 1;
	k1->height = Max(height(k1->right), k2->height) + 1;
	k2 = k1;

}

template<typename Comparable>
void AVLTree<Comparable>::doubleWithLeftChild(AVLNode *& k3)//左右旋转
{
	rotateWithRightChild(k3->left);
	rotateWithLeftChild(k3);
}

template<typename Comparable>
void AVLTree<Comparable>::doubleWithRightChild(AVLNode *& k3)//右左旋转
{
	rotateWithLeftChild(k3->right);
	rotateWithRightChild(k3);
}

template<typename Comparable>
void AVLTree<Comparable>::balance(AVLNode *& t)
{
	if (t == nullptr)
	{
		return;
	}
	if (height(t->left) - height(t->right) > ALLOWED_IMBLANCE)
		if (height(t->left->left) >= height(t->left->right))
			rotateWithLeftChild(t);
		else
			doubleWithLeftChild(t);
	else if(height(t->right) - height(t->left) > ALLOWED_IMBLANCE)
		if (height(t->right->right) >= height(t->right->left))
			rotateWithRightChild(t);
		else
			doubleWithRightChild(t);
	t->height = max(height(t->left), height(t->right)) + 1;
}

C#实现

    public class AVLTree<T> where T : IComparable<T>
    {
        public class AVLNode
        {
           public T element;
           public AVLNode Left;
           public AVLNode Right;
           public int Height;
           public AVLNode(T e, AVLNode l, AVLNode r,int h = 0)
           {
                element = e;
                Left = l;
                Right = r;
                Height = h;
           }
          
        };
        private const int ALLOWED_IMBLANCE = 1;
        private AVLNode Root;

        public AVLTree()
        {
            Root = null;
        }
        public AVLTree(AVLTree<T> other)
        {
            Root = Clone(other.Root);
        }
        ~AVLTree()
        {
            MakeEmpty();
        }
        private void Insert(T x,ref AVLNode t)
        {
            if(t == null)
            {
                t = new AVLNode(x, null, null);
            }
            else if (x.CompareTo(t.element) < 0)
            {
                Insert(x, ref t.Left);
                if (Height(t.Left) - Height(t.Right) == 2)
                    if (x.CompareTo(t.Left.element) < 0)
                        RotateWithLeftChild(ref t);
                    else
                        DoubleWithLeftChild(ref t);

            }
            else if(x.CompareTo(t.element) > 0)
            {
                Insert(x, ref t.Right);
                if (Height(t.Right) - Height(t.Left) == 2)
                    if (x.CompareTo(t.Right.element) > 0)
                        RotateWithRightChild(ref t);
                    else
                        DoubleWithRightChild(ref t);
            }
            t.Height = Max(Height(t.Left), Height(t.Right)) + 1;

        }
        private void Insert(ref AVLNode t,params T[] paramList)
        {
          foreach(var temp in paramList)
          {
                Insert(temp, ref t);
          }
        }
        private void Remove(T x, ref AVLNode t)
        {
            if(t == null)
            {
                return;
            }
            if (x.CompareTo(t.element) < 0)
            {
                Remove(x, ref t.Left);
            }
            else if(x.CompareTo(t.element) > 0)
            {
                Remove(x, ref t.Right);
            }
            else if(t.Left != null && t.Right != null)
            {
                t.element = FindMin(t);
                Remove(t.element, ref t.Right);
            }
            else
            {
                AVLNode oldNode = t;
                t = t.Left ?? t.Right;
                oldNode = null;
            }
            Balance(ref t);
        }
        private T FindMin(AVLNode t)
        {
            if (t != null)
                while (t.Left != null)
                    t = t.Right;
            return t.element;
        }
        private T FindMax(AVLNode t)
        {
            if (t != null)
                while (t.Right != null)
                    t = t.Right;
            return t.element;
        }
        private bool Contains(T x, AVLNode t)
        {
            while (t != null)
            {
                if (x.CompareTo(t.element) < 0)
                    t = t.Left;
                else if (x.CompareTo(t.element) > 0)
                    t = t.Right;
                else
                    return true;
            }
            return false;
        }
        private void MakeEmpty(ref AVLNode t)
        {
            if(t != null)
            {
                MakeEmpty(ref t.Left);
                MakeEmpty(ref t.Right);
                t = null;
            }
        }
        private void PrintTree(AVLNode t)
        {
            if(t != null)
            {
                Console.WriteLine($"{t.element} ");
                PrintTree(t.Left);
                PrintTree(t.Right);
            }
        }
        private AVLNode Clone(AVLNode t)
        {
            if(t == null)
            {
                return null;
            }
            return new AVLNode(t.element, Clone(t.Left), Clone(t.Right));
        }
        private int Max(int a, int b)
        {
            return (a > b) ? a : b;
        }
        private void RotateWithLeftChild(ref AVLNode k2)//左旋
        {
            AVLNode k1 = k2.Left;
            k2.Left = k1.Right;
            k1.Right = k2;
            k2.Height = Max(Height(k2.Left), Height(k2.Right)) + 1;
            k1.Height = Max(Height(k1.Left), k2.Height) + 1;
            k2 = k1;
        }
        private void RotateWithRightChild(ref AVLNode k2)
        {
            AVLNode k1 = k2.Right;
            k2.Right = k1.Left;
            k1.Left = k2;
            k2.Height = Max(Height(k2.Right), Height(k2.Left)) + 1;
            k1.Height = Max(Height(k1.Right), k2.Height) + 1;
            k2 = k1;

        }
        private void DoubleWithLeftChild(ref AVLNode k3)
        {
            RotateWithRightChild(ref k3.Left);
            RotateWithLeftChild(ref k3);
        }
        private void DoubleWithRightChild(ref AVLNode k3)
        {
            RotateWithLeftChild(ref k3.Right);
            RotateWithRightChild(ref k3);
        }
        private void Balance(ref AVLNode t)
        {
            if (t == null)
            {
                return;
            }
            if (Height(t.Left) - Height(t.Right) > ALLOWED_IMBLANCE)
                if (Height(t.Left.Left) >= Height(t.Left.Right))
                    RotateWithLeftChild(ref t);
                else
                    DoubleWithLeftChild(ref t);
            else if (Height(t.Right) - Height(t.Left) > ALLOWED_IMBLANCE)
                if (Height(t.Right.Right) >= Height(t.Right.Left))
                    RotateWithRightChild(ref t);
                else
                    DoubleWithRightChild(ref t);
            t.Height = Max(Height(t.Left), Height(t.Right)) + 1;
        }
        public bool Contains(T x)
        {
            return Contains(x, Root);
        }
        public bool IsEmpty()
        {
            return Root == null;
        }
        public void PrintTree()
        {
            PrintTree(Root);
        }
        public void MakeEmpty()
        {
            MakeEmpty(ref Root);
        }
        public void Insert(T x)
        {
            Insert(x, ref Root);
        }
        public void Insert(params T[] paramList)
        {
            Insert(ref Root, paramList);
        }
        public void Remove(T x)
        {
            Remove(x, ref Root);
        }
        public T FindMin()
        {
            return FindMin(Root);
        }
        public T FindMax()
        {
            return FindMax(Root);
        }
        public int Height(AVLNode t) { return t == null ? -1 : t.Height; }

    }

你可能感兴趣的:(数据结构,平衡二叉树,AVL树,C/C++实现,C#实现)