这是之前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_