C++ AVL树(改进版)

这是之前C语言AVL树的改进版,遵循了严格的封装和面向对象的思想。有不足之处请指正!

main.cpp

/*
测试用例 1
    输入
        49 64 57 24 12 81 36
    输出
                            81
                    64
            57
                            49
                                    36
                    24
                            12

测试用例 2
    输入
        81 12 64 24 36 57 49
    输出
                            81
                64
                        57
                                49
        36
                24
                        12

测试用例 3
    输入
        36 28 12 54 79 42 81 95
    输出
                                95
                        81
                                79
                54
                        42
        36
                28
                        12

测试用例 4
    输入
        8 11 15 6 17 12 1 0 9 2 13 16 18 10 3 14 7 4 5 19
    输出
                                         19
                                18
                        17
                                16
                15
                                14
                        13
                                12
        11
                                10
                        9
                                8
                                        7
                6
                                        5
                                4
                        3
                                        2
                                1
                                        0
*/
#include "Test.h"

int main()
{
	Test();

	system("pause");
	return 0;
}

Test.h

#pragma once
#ifndef _Test_h_
#define _Test_h_

#include "AVLTree.h"
#include <cctype>

void Test()
{
	AVLTREE::AVLTree<double> tree;
	AVLTREE::Node<double>* p;
	double element;
	char choice;

	do
	{
		std::cout << "F-查找 L-最大 T-最小 M-中序 S-个数 I-输入 O-输出 C-清空 N-插入 R-删除 Q-退出 > ";
		std::cin >> choice;
		while (std::cin.get() != '\n');
		choice = toupper(choice);

		switch (choice)
		{
		case 'F':
			std::cout << "查找 > ";
			std::cin >> element;
			p = tree.Find(element);
			if (p)
			{
				std::cout << p << " -> " << p->Data() << std::endl;
			}
			else
			{
				std::cout << "该元素不存在!\n";
			}
			break;
		case 'L':
			p = tree.FindMax();
			if (p)
			{
				std::cout << "最大元素为:" << p->Data() << std::endl;
			}
			else
			{
				std::cout << "该元素不存在!\n";
			}
			break;
		case 'T':
			p = tree.FindMin();
			if (p)
			{
				std::cout << "最小元素为:" << p->Data() << std::endl;
			}
			else
			{
				std::cout << "该元素不存在!\n";
			}
			break;
		case 'M':
			tree.Inorder();
			break;
		case 'S':
			std::cout << "结点个数为:" << tree.Size() << std::endl;
			break;
		case 'I':
			std::cout << "输入 > ";
			tree.Input();
			break;
		case 'O':
			tree.Output();
			break;
		case 'C':
			std::cout << "清空\n";
			tree.Clear();
			break;
		case 'N':
			std::cout << "插入 > ";
			std::cin >> element;
			tree.Insert(element);
			break;
		case 'R':
			std::cout << "删除 > ";
			std::cin >> element;
			tree.Remove(element);
			break;
		case 'Q':
			std::cout << "退出\n";
			break;
		default:
			std::cout << "不正确的选项!\n";
			break;
		}

	} while (choice != 'Q');
}

#endif // !_Test_h_

AVLTree.h

#pragma once
#ifndef _AVLTree_h_
#define _AVLTree_h_

#include "Node.h"
#include <cmath>

namespace AVLTREE
{
	template <typename T>
	class AVLTree
	{
	public:
		AVLTree();
		~AVLTree();

		Node<T>* Find(const T& data) const;
		Node<T>* FindMax() const;
		Node<T>* FindMin() const;
		void Inorder() const;
		int Size() const;
		void Output() const;
		void Clear();
		void Insert(const T& data);
		void Remove(const T& data);
		void Input();

	private:
		Node<T>* root; // 根节点
		int count; // 结点个数

		static Node<T>* Find(Node<T>* root, const T& data);
		static Node<T>* FindMin(Node<T>* root);
		static Node<T>* FindMax(Node<T>* root);
		static void Inorder(Node<T>* root);
		static void Output(const Node<T>* root, int level);
		static void Clear(Node<T>** root);
		static Node<T>* Insert(Node<T>** root, const T& data, int& count);
		static Node<T>* Remove(Node<T>** root, const T& data, int& count);

		static int Depth(Node<T>* root);
		static int Max(const int x, const int y);
		static Node<T>* LL_type(Node<T>** K2); // LL 左旋
		static Node<T>* LR_type(Node<T>** K3); // LR 先左旋再右旋
		static Node<T>* RR_type(Node<T>** K2); // RR 右旋
		static Node<T>* RL_type(Node<T>** K3); // RL 先右旋再左旋
	};

	template<typename T>
	inline AVLTree<T>::AVLTree()
		: root(nullptr), count(0) {}

	template<typename T>
	inline AVLTree<T>::~AVLTree()
	{
		Clear();
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::Find(const T& data) const
	{
		return Find(root, data);
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::FindMax() const
	{
		return FindMax(root);
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::FindMin() const
	{
		return FindMin(root);
	}

	template<typename T>
	inline void AVLTree<T>::Inorder() const
	{
		Inorder(root);
		std::cout << std::endl;
	}

	template<typename T>
	inline int AVLTree<T>::Size() const
	{
		return count;
	}

	template<typename T>
	inline void AVLTree<T>::Output() const
	{
		Output(root, 0);
	}

	template<typename T>
	inline void AVLTree<T>::Clear()
	{
		Clear(&root);
		root = nullptr;
		count = 0;
	}

	template<typename T>
	inline void AVLTree<T>::Insert(const T& data)
	{
		root = Insert(&root, data, count);
	}

	template<typename T>
	inline void AVLTree<T>::Remove(const T& data)
	{
		root = Remove(&root, data, count);
	}

	template<typename T>
	void AVLTree<T>::Input()
	{
		Clear();
		T element;
		while (std::cin >> element)
		{
			Insert(element);
			if (std::cin.peek() == '\n')
			{
				break;
			}
		}
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::Find(Node<T>* root, const T& data)
	{
		if (root)
		{
			if (data < root->Data())
			{
				return Find(root->Left(), data);
			}
			else if (data > root->Data())
			{
				return Find(root->Right(), data);
			}
		}
		return root;
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::FindMin(Node<T>* root)
	{
		if (!root)
		{
			return nullptr;
		}
		else if (!root->Left())
		{
			return root;
		}
		else
		{
			return FindMin(root->Left());
		}
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::FindMax(Node<T>* root)
	{
		if (root)
		{
			while (root->Right())
			{
				root = root->Right();
			}
		}
		return root;
	}

	template<typename T>
	inline void AVLTree<T>::Inorder(Node<T>* root)
	{
		if (root)
		{
			Inorder(root->Left());
			std::cout << root->Data() << ' ';
			Inorder(root->Right());
		}
	}

	template<typename T>
	inline void AVLTree<T>::Output(const Node<T>* root, int level)
	{
		if (root)
		{
			Output(root->Right(), level + 1);
			for (int i = 0; i < level; i++)
			{
				std::cout << "	";
			}
			std::cout << root->Data() << std::endl;
			Output(root->Left(), level + 1);
		}
	}

	template<typename T>
	inline void AVLTree<T>::Clear(Node<T>** root)
	{
		Node<T>* p = nullptr;
		if (*root)
		{
			p = (*root)->Left();
			Clear(&p);
			(*root)->Left(nullptr);
			p = (*root)->Right();
			Clear(&p);
			(*root)->Right(nullptr);
			delete *root;
		}
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::Insert(Node<T>** root, const T& data, int& count)
	{
		Node<T>* p = nullptr;
		if (!*root)
		{
			*root = new Node<T>(data);
			count++;
		}
		else if (data < (*root)->Data())
		{
			p = (*root)->Left();
			(*root)->Left(Insert(&p, data, count)); // 左递归
			if (Depth((*root)->Left()) - Depth((*root)->Right()) > 1) // 不平衡
			{
				p = (*root)->Left();
				if (data < p->Data()) // LL
				{
					*root = LL_type(root);
				}
				else // LR
				{
					*root = LR_type(root);
				}
			}
		}
		else if (data > (*root)->Data())
		{
			p = (*root)->Right();
			(*root)->Right(Insert(&p, data, count)); // 右递归
			if (Depth((*root)->Right()) - Depth((*root)->Left()) > 1) // 不平衡
			{
				p = (*root)->Right();
				if (data > p->Data()) // RR
				{
					*root = RR_type(root);
				}
				else // RL
				{
					*root = RL_type(root);
				}
			}
		}
		/*else x 已经在树中,无需添加*/

		(*root)->Depth(Max(Depth((*root)->Left()), Depth((*root)->Right())) + 1);
		return *root;
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::Remove(Node<T>** root, const T& data, int& count)
	{
		Node<T>* p, * temp;
		if (!*root)
		{
			std::cout << "Element not found!\n";
		}
		else if (data < (*root)->Data()) //往左走
		{
			p = (*root)->Left();
			(*root)->Left(Remove(&p, data, count)); // 左递归
			if (Depth((*root)->Left()) - Depth((*root)->Right()) > 1) // 不平衡
			{
				p = (*root)->Left();
				if (data < p->Data()) // LL
				{
					*root = LL_type(root);
				}
				else // LR
				{
					*root = LR_type(root);
				}
			}
		}
		else if (data > (*root)->Data()) //往右走
		{
			p = (*root)->Right();
			(*root)->Right(Remove(&p, data, count)); // 右递归
			if (Depth((*root)->Right()) - Depth((*root)->Left()) > 1) // 不平衡
			{
				p = (*root)->Right();
				if (data > p->Data()) // RR
				{
					*root = RR_type(root);
				}
				else // RL
				{
					*root = RL_type(root);
				}
			}
		}
		else if (data == (*root)->Data()) //如果就是要删除的节点
		{
			if ((*root)->Left() && (*root)->Right()) // 有左右儿子
			{
				if (Depth((*root)->Left()) > Depth((*root)->Right()))
				{
					/*
					如果左子树比右子树深
					则找出左子树中的最大节点
					将该最大节点的值赋值给 root
					删除该最大节点
					这类似于用 root 的左子树中最大节点做 root 的替身
					删除 root 的左子树中最大节点之后,AVL树仍然是平衡的
					*/
					Node<T>* max = FindMax((*root)->Left());
					(*root)->Data(max->Data());
					p = (*root)->Left();
					(*root)->Left(Remove(&p, max->Data(), count));
				}
				else
				{
					/*
					如果右子树比左子树深
					则找出左子树中的最小节点
					将该最小节点的值赋值给 root
					删除该最小节点
					这类似于用 root 的右子树中最小节点做 root 的替身
					删除 root 的左子树中最小节点之后,AVL树仍然是平衡的
					*/
					Node<T>* min = FindMin((*root)->Right());
					(*root)->Data(min->Data());
					p = (*root)->Right();
					(*root)->Right(Remove(&p, min->Data(), count));
				}
			}
			else // 有一个或零个儿子
			{
				temp = *root;
				if (!(*root)->Left()) // 没有左儿子
				{
					*root = (*root)->Right();
				}
				else if (!(*root)->Right()) // 没有右儿子
				{
					*root = (*root)->Left();
				}
				delete temp;
				count--;
			}
		}

		if (*root)
		{
			(*root)->Depth(Max(Depth((*root)->Left()), Depth((*root)->Right())) + 1);
		}
		return *root;
	}

	template<typename T>
	inline int AVLTree<T>::Depth(Node<T>* root)
	{
		return root ? root->Depth() : -1;
	}

	template<typename T>
	inline int AVLTree<T>::Max(const int x, const int y)
	{
		return x > y ? x : y;
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::LL_type(Node<T>** K2)
	{
		Node<T>* K1 = (*K2)->Left();
		(*K2)->Left(K1->Right());
		K1->Right(*K2);

		(*K2)->Depth(Max(Depth((*K2)->Left()), Depth((*K2)->Right())) + 1);
		K1->Depth(Max(Depth(K1->Left()), (*K2)->Depth()) + 1);

		return K1; // 新的根结点
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::LR_type(Node<T>** K3)
	{
		Node<T>* K1 = (*K3)->Left();
		Node<T>* K2 = K1->Right();
		K1->Right(K2->Left());
		(*K3)->Left(K2->Right());
		K2->Left(K1);
		K2->Right(*K3);

		K1->Depth(Max(Depth(K1->Left()), Depth(K1->Right())) + 1);
		(*K3)->Depth(Max(Depth((*K3)->Left()), Depth((*K3)->Right())) + 1);
		K2->Depth(Max(K1->Depth(), (*K3)->Depth()) + 1);

		return K2; // 新的根结点
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::RR_type(Node<T>** K2)
	{
		Node<T>* K1 = (*K2)->Right();
		(*K2)->Right(K1->Left());
		K1->Left(*K2);

		(*K2)->Depth(Max(Depth((*K2)->Left()), Depth((*K2)->Right())) + 1);
		K1->Depth(Max(Depth(K1->Right()), (*K2)->Depth()) + 1);

		return K1; // 新的根结点
	}

	template<typename T>
	inline Node<T>* AVLTree<T>::RL_type(Node<T>** K3)
	{
		Node<T>* K1 = (*K3)->Right();
		Node<T>* K2 = K1->Left();
		K1->Left(K2->Right());
		(*K3)->Right(K2->Left());
		K2->Right(K1);
		K2->Left(*K3);

		K1->Depth(Max(Depth(K1->Left()), Depth(K1->Right())) + 1);
		(*K3)->Depth(Max(Depth((*K3)->Left()), Depth((*K3)->Right())) + 1);
		K2->Depth(Max(K1->Depth(), (*K3)->Depth()) + 1);

		return K2; // 新的根结点
	}

} // end namespace AVLTREE

#endif // !_AVLTree_h_

Node.h

#pragma once
#ifndef _Node_h_
#define _Node_h_

#include <iostream>

namespace AVLTREE
{
	template <typename T>
	class Node
	{
	public:
		Node();
		Node(const T& data);

		// getter
		T Data() const;
		Node<T>* Left() const;
		Node<T>* Right() const;
		int Depth() const;

		// setter
		void Data(const T& data);
		void Left(Node<T>* const left);
		void Right(Node<T>* const right);
		void Depth(const int depth);

	private:
		T data;
		Node<T>* left;
		Node<T>* right;
		int depth; // 深度
	};

	template <typename T>
	inline Node<T>::Node()
		: data(T()), left(nullptr), right(nullptr), depth(0) {}

	template <typename T>
	inline Node<T>::Node(const T& data)
		: data(data), left(nullptr), right(nullptr), depth(0) {}

	// getter
	template <typename T>
	inline T Node<T>::Data() const
	{
		return data;
	}

	template <typename T>
	inline Node<T>* Node<T>::Left() const
	{
		return left;
	}

	template <typename T>
	inline Node<T>* Node<T>::Right() const
	{
		return right;
	}

	template <typename T>
	inline int Node<T>::Depth() const
	{
		return depth;
	}

	// setter
	template <typename T>
	inline void Node<T>::Data(const T& data)
	{
		this->data = data;
	}

	template <typename T>
	inline void Node<T>::Left(Node<T>* const left)
	{
		this->left = left;
	}

	template <typename T>
	inline void Node<T>::Right(Node<T>* const right)
	{
		this->right = right;
	}

	template <typename T>
	inline void Node<T>::Depth(const int depth)
	{
		this->depth = depth;
	}

} // end namespace AVLTREE

#endif // !_Node_h_

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值