目录
前言:为什么需要平衡二叉树?
二叉搜索树的局限性
相对于链表,二叉搜索树的静态查找具有高效性。但是,如果我们希望一棵二叉树既能实现查找操作,又能实现插入和删除操作,也就是数据的动态查找 ,情况就有所不同了。
例:按如下顺序向二叉搜索树中插入数据。
1 2 3 4 5… …
由二叉搜索树的性质,新生成的二叉搜索树结点只有右子树(叶节点除外),因此二叉搜索树的一部分会退化成链表,不再具有查找的高效性。删除操作同理,也可能破坏二叉搜索树的查找高效性。
我们希望二叉树在插入和删除操作时,能够自动调整结点的相对位置,不使某个查找路径过长或过短。要实现这个功能,需要改进二叉搜索树。
什么是平衡二叉树?
平衡二叉树,又叫AVL树,是牺牲了插入和删除效率,以提高查找效率的特殊二叉搜索树。
平衡二叉树的递归定义
1)平衡二叉树可以是空树。
2)如果平衡二叉树不是空树,那它的左右子树高度差小于等于1。
3)平衡二叉树如果存在子树,那它的子树也是平衡二叉树。
平衡二叉树的功能
template<class T> //定义一个储存数据类型T的平衡二叉树
class AVL {
private:
struct TreeNode; //树的结点
typedef TreeNode*NodePtr; //指向树的结点的指针
static T out_of_range; //防止访问越界的变量
int height(NodePtr node)const; //返回树的高度
bool balanced(NodePtr node)const; //根据定义判断是否为AVL树:定义参见上文
void RightRightRotation(NodePtr unbalanced_node); //右单旋
void LeftLeftRotation(NodePtr unbalanced_node); //左单旋
void LeftRightRotation(NodePtr unbalanced_node); //LR双旋
void RightLeftRotation(NodePtr unbalanced_node); //RL双旋
int _size; //树的总结点数
protected:
NodePtr root; //根结点
public:
//重载流插入运算符
template<class U>
friend ostream&operator<<(ostream&output, AVL<U>const&x);
AVL(); //构造函数
~AVL(); //析构函数
AVL(AVL const&object); //重载复制构造函数:防止内存泄漏
int find(T search_element)const; //查找数据的抽象位置
bool exist(T search_element)const; //判断数据是否存在:二分查找实现
T const&max()const; //查找最大元素
T const&min()const; //查找最小元素
void insert(T insert_element); //插入
void erase(T erase_element); //删除
void clear(); //清空
inline int size()const; //返回树的总结点数
inline bool empty()const; //判断是否为空树
void operator=(AVL const&another); //重载赋值运算符:防止内存泄漏
bool operator==(AVL const&another)const; //判断两棵AVL树是否相等
bool operator!=(AVL const&another)const; //判断两棵AVL树是否不相等
};
平衡性调整:向上调整,4种方式
容易证明:当多个结点的平衡性被破坏时,调整了下面的结点,上面的结点就恢复了平衡性。
具体有如下4种调整方式:
右单旋
template<class T>
void AVL<T>::RightRightRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child;
l_child = new TreeNode(unbalanced_node->data);
l_child->left = unbalanced_node->left;
l_child->right = unbalanced_node->right->left;
r_child = unbalanced_node->right->right;
unbalanced_node->data = unbalanced_node->right->data;
delete unbalanced_node->right;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
左单旋
template<class T>
void AVL<T>::LeftLeftRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child;
l_child = unbalanced_node->left->left;
r_child = new TreeNode(unbalanced_node->data);
r_child->left = unbalanced_node->left->right;
r_child->right = unbalanced_node->right;
unbalanced_node->data = unbalanced_node->left->data;
delete unbalanced_node->left;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
LR双旋
template<class T>
void AVL<T>::LeftRightRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child, temp;
r_child = new TreeNode(unbalanced_node->data);
r_child->left = unbalanced_node->left->right->right;
r_child->right = unbalanced_node->right;
l_child = unbalanced_node->left;
temp = l_child->right;
l_child->right = unbalanced_node->left->right->left;
unbalanced_node->data = temp->data;
delete temp;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
RL双旋
template<class T>
void AVL<T>::RightLeftRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child, temp;
l_child = new TreeNode(unbalanced_node->data);
l_child->left = unbalanced_node->left;
l_child->right = unbalanced_node->right->left->left;
r_child = unbalanced_node->right;
temp = r_child->left;
r_child->left = unbalanced_node->right->left->right;
unbalanced_node->data = temp->data;
delete temp;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
插入:1种情况
插入操作分为3个步骤:
1)查找插入位置
2)插入新结点:新结点一定是叶结点
3)平衡性调整:向上调整
template<class T>
void AVL<T>::insert(T insert_element) {
if (empty()) {
root = new TreeNode(insert_element);
return;
}
stack<NodePtr>S;
cirque<bool, 2>Q;
NodePtr it = root;
while (it->data != insert_element) {
S.push(it);
if (it->data > insert_element) {
if (!it->left) {
it->left = new TreeNode(insert_element);
_size++;
break;
}
else it = it->left;
}
else {
if (!it->right) {
it->right = new TreeNode(insert_element);
_size++;
break;
}
else it = it->right;
}
}
NodePtr last_node, this_node = it;
while (!S.empty()) {
last_node = this_node;
this_node = S.top();
S.pop();
Q.push(last_node == this_node->left ? true : false);
if (2 == Q.size())
if (!balanced(this_node)) {
if (Q.rear() && Q.front()) LeftLeftRotation(this_node);
else if (!Q.rear() && !Q.front()) RightRightRotation(this_node);
else if (Q.rear()) LeftRightRotation(this_node);
else RightLeftRotation(this_node);
break;
}
}
}
删除:3种情况
插入操作分为3个步骤:
1)查找要删除的结点
2)根据要删除的结点的位置,分情况处理:
情况1:叶结点=>直接删除
情况2:不是叶结点,但是只有一个子结点=>把子结点赋值给该结点,删除子结点
情况3:不是叶结点,并且有两个子结点=>找到左子树的最大结点,并与其交换位置,删除左子树的最大结点
3)平衡性调整:向上调整
template<class T>
void AVL<T>::erase(T erase_element) {
if (empty())return;
stack<NodePtr>S;
auto it = root;
while (it) {
S.push(it);
if (erase_element < it->data)it = it->left;
else if (erase_element > it->data)it = it->right;
else if (!it->left && !it->right) {
S.pop();
if (it == root)root = NULL;
else if (it == S.top()->left)S.top()->left = NULL;
else S.top()->right = NULL;
delete it;
_size--;
break;
}
else if (!it->left&&it->right) {
it->data = it->right->data;
it->left = it->right->left;
NodePtr temp = it->right->right;
delete it->right;
it->right = temp;
break;
}
else if (it->left && !it->right) {
it->data = it->left->data;
it->right = it->left->right;
NodePtr temp = it->left->left;
delete it->left;
it->left = temp;
break;
}
else {
NodePtr finder = it;
it = it->left;
while (it) {
S.push(it);
it = it->right;
}
it = S.top();
finder->data = it->data;
if (!it->left && !it->right) {
S.pop();
if (it == S.top()->left)S.top()->left = NULL;
else S.top()->right = NULL;
delete it;
_size--;
break;
}
else if (!it->left&&it->right) {
it->data = it->right->data;
it->left = it->right->left;
NodePtr temp = it->right->right;
delete it->right;
it->right = temp;
break;
}
else {
it->data = it->left->data;
it->right = it->left->right;
NodePtr temp = it->left->left;
delete it->left;
it->left = temp;
break;
}
}
}
if (S.empty())return;
NodePtr last_node, this_node = S.top();
S.pop();
if (!balanced(this_node)) {
if (this_node->left)LeftLeftRotation(this_node);
else RightRightRotation(this_node);
return;
}
bool flag;
while (!S.empty()) {
last_node = this_node;
this_node = S.top();
S.pop();
flag = last_node == this_node->left ? true : false;
if (!balanced(this_node)) {
if (flag) LeftLeftRotation(this_node);
else RightRightRotation(this_node);
break;
}
}
}
求树的高度:后序遍历实现
树的高度的递归定义:
树的高度=MAX(左子树高度,右子树高度)+1
所以先求左子树高度,再求右子树高度,最后访问根结点,由后序遍历实现。
template<class T>
int AVL<T>::height(AVL<T>::NodePtr node)const {
if (!node)return 0;
stack<NodePtr>S;
NodePtr it = node;
int path = 1, longest_path = 1;
do {
while (it->left) {
S.push(it);
it = it->left;
path++;
}
if (it->right) {
S.push(it);
it = it->right;
path++;
}
else {
if (path > longest_path)longest_path = path;
while (!S.empty()) {
while (it == S.top()->left && !S.top()->right ||
it == S.top()->right && !S.top()->left) {
it = S.top();
S.pop();
path--;
if (S.empty()) return longest_path;
}
if (it == S.top()->left) {
it = S.top()->right;
break;
}
else {
it = S.top();
S.pop();
path--;
}
}
}
} while (!S.empty());
return longest_path;
}
判断是否为平衡二叉树
该方法的实现需要调用height()方法:返回树的高度。
根据平衡二叉树的定义:
(左子树高度-右子树高度)的绝对值<=1,则为平衡二叉树。
template<class T>
bool AVL<T>::balanced(AVL<T>::NodePtr node)const {
if (!node)return true;
int BF = height(node->left) - height(node->right);
return -1 <= BF && BF <= 1 ? true : false;
}
输出平衡二叉树的信息:中序遍历实现
平衡二叉树是特殊的二叉查找树,所以采用中序遍历输出信息。
template<class U>
ostream&operator<<(ostream&output, AVL<U>const&x) {
if (x.empty())return output;
stack<AVL<U>::NodePtr>S;
typename AVL<U>::NodePtr it = x.root;
while (it || !S.empty()) {
while (it) {
S.push(it);
it = it->left;
}
if (!S.empty()) {
output << S.top()->data << ' ';
it = S.top()->right;
S.pop();
}
}
return output;
}
判断两棵AVL树是否相等
两棵相等的AVL树的中序遍历应该相同。
template<class T>
bool AVL<T>::operator==(AVL<T> const&another)const {
if (empty() ^ another.empty())return false;
if (empty() && another.empty())return true;
if (size() != another.size())return false;
stack<NodePtr>S;
NodePtr it = root;
while (it || !S.empty()) {
while (it) {
if (!another.exist(it->data))return false;
S.push(it);
it = it->left;
}
if (!S.empty()) {
it = S.top()->right;
S.pop();
}
}
return true;
}
平衡二叉树的赋值:防止内存泄漏
复制构造函数和赋值运算符都应该做到以下两点:
1)赋值前应该先清空当前平衡二叉树,防止内存泄漏
2)依次创建新的结点,防止两棵平衡二叉树有交叉结点
template<class T>
void AVL<T>::operator=(AVL<T> const&another) {
clear();
if (another.empty())return;
stack<NodePtr>S;
NodePtr it = another.root;
while (it || !S.empty()) {
while (it) {
insert(it->data);
S.push(it);
it = it->left;
}
if (!S.empty()) {
it = S.top()->right;
S.pop();
}
}
}
清空:后序遍历,释放所有结点
清空操作只能由后序遍历实现,析构函数可以调用clear()方法实现。
template<class T>
void AVL<T>::clear() {
_size = 0;
if (empty())return;
stack<NodePtr>S;
NodePtr it = root;
do {
while (it->left) {
S.push(it);
it = it->left;
}
if (it->right) {
S.push(it);
it = it->right;
}
else while (!S.empty()) {
while (it == S.top()->left && !S.top()->right ||
it == S.top()->right && !S.top()->left) {
delete it;
it = S.top();
S.pop();
if (S.empty()) {
delete it;
return;
}
}
if (it == S.top()->left) {
delete it;
it = S.top()->right;
break;
}
else {
delete it;
it = S.top();
S.pop();
if (S.empty()) {
delete it;
return;
}
}
}
} while (!S.empty());
root = NULL;
}
完整代码
//平衡二叉树:AVL树
#ifndef OCAVL_H
#define OCAVL_H
#include<iostream>
using std::ostream;
#include"OCstack.h"
using OC::stack;
#include"OCcirque.h"
using OC::cirque;
#ifndef _OC_BEGIN
#define _OC_BEGIN namespace OC{
#endif
#ifndef _OC_END
#define _OC_END }
#endif
#ifndef NULL
#define NULL 0
#endif
#ifndef EOF
#define EOF -1
#endif
#ifndef OCAVL_DEBUG
#define OCAVL_DEBUG 0
#endif
#if OCAVL_DEBUG
#include"OCqueue.h"
using OC::queue;
#endif
_OC_BEGIN
template<class T>
class AVL {
private:
struct TreeNode; //树的结点
typedef TreeNode*NodePtr; //指向树的结点的指针
static T out_of_range; //越界变量
int height(NodePtr node)const; //树的高度
bool balanced(NodePtr node)const; //判断是否为AVL树
void RightRightRotation(NodePtr unbalanced_node); //右单旋
void LeftLeftRotation(NodePtr unbalanced_node); //左单旋
void LeftRightRotation(NodePtr unbalanced_node); //LR双旋
void RightLeftRotation(NodePtr unbalanced_node); //RL双旋
int _size; //树的结点数
protected:
NodePtr root; //根结点
public:
//重载赋值运算符
template<class U>
friend ostream&operator<<(ostream&output, AVL<U>const&x);
AVL(); //构造函数
~AVL(); //析构函数
AVL(AVL const&object); //复制构造函数
int find(T search_element)const; //查找
bool exist(T search_element)const; //二分查找
T const&max()const; //查找最大元素
T const&min()const; //查找最小元素
void insert(T insert_element); //插入
void erase(T erase_element); //删除
void clear(); //清空
inline int size()const; //树的结点数
inline bool empty()const; //返回是否为空树
void operator=(AVL const&another); //重载赋值运算符
bool operator==(AVL const&another)const; //判断两棵AVL树是否相等
bool operator!=(AVL const&another)const; //判断两棵AVL树是否不相等
#if OCAVL_DEBUG
void LevelOrdertraversal()const {
if (empty())return;
queue<NodePtr>Q;
NodePtr it = root;
Q.push(it);
while (!Q.empty()) {
it = Q.front();
Q.pop();
cout << it->data << ' ';
if (it->left)Q.push(it->left);
if (it->right)Q.push(it->right);
}
}
#endif
};
//_TREENODE_BEGIN
template<class T>
struct AVL<T>::TreeNode {
typedef TreeNode*NodePtr;
T data; //数据域
NodePtr left, right; //指针域
TreeNode(T init_element); //构造函数
};
template<class T>
AVL<T>::TreeNode::TreeNode(T init_element) :data(init_element), left(NULL), right(NULL) {
}
//_TREENODE_END
//越界变量
template<class T>
T AVL<T>::out_of_range;
//树的高度:后序遍历实现
template<class T>
int AVL<T>::height(AVL<T>::NodePtr node)const {
if (!node)return 0;
stack<NodePtr>S;
NodePtr it = node;
int path = 1, longest_path = 1;
do {
while (it->left) {
S.push(it);
it = it->left;
path++;
}
if (it->right) {
S.push(it);
it = it->right;
path++;
}
else {
if (path > longest_path)longest_path = path;
while (!S.empty()) {
while (it == S.top()->left && !S.top()->right ||
it == S.top()->right && !S.top()->left) {
it = S.top();
S.pop();
path--;
if (S.empty()) return longest_path;
}
if (it == S.top()->left) {
it = S.top()->right;
break;
}
else {
it = S.top();
S.pop();
path--;
}
}
}
} while (!S.empty());
return longest_path;
}
//判断是否为AVL树
template<class T>
bool AVL<T>::balanced(AVL<T>::NodePtr node)const {
if (!node)return true;
int BF = height(node->left) - height(node->right);
return -1 <= BF && BF <= 1 ? true : false;
}
//_ROTATION_BEING
//右单旋
template<class T>
void AVL<T>::RightRightRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child;
l_child = new TreeNode(unbalanced_node->data);
l_child->left = unbalanced_node->left;
l_child->right = unbalanced_node->right->left;
r_child = unbalanced_node->right->right;
unbalanced_node->data = unbalanced_node->right->data;
delete unbalanced_node->right;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
//左单旋
template<class T>
void AVL<T>::LeftLeftRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child;
l_child = unbalanced_node->left->left;
r_child = new TreeNode(unbalanced_node->data);
r_child->left = unbalanced_node->left->right;
r_child->right = unbalanced_node->right;
unbalanced_node->data = unbalanced_node->left->data;
delete unbalanced_node->left;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
//LR双旋
template<class T>
void AVL<T>::LeftRightRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child, temp;
r_child = new TreeNode(unbalanced_node->data);
r_child->left = unbalanced_node->left->right->right;
r_child->right = unbalanced_node->right;
l_child = unbalanced_node->left;
temp = l_child->right;
l_child->right = unbalanced_node->left->right->left;
unbalanced_node->data = temp->data;
delete temp;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
//RL双旋
template<class T>
void AVL<T>::RightLeftRotation(AVL<T>::NodePtr unbalanced_node) {
NodePtr l_child, r_child, temp;
l_child = new TreeNode(unbalanced_node->data);
l_child->left = unbalanced_node->left;
l_child->right = unbalanced_node->right->left->left;
r_child = unbalanced_node->right;
temp = r_child->left;
r_child->left = unbalanced_node->right->left->right;
unbalanced_node->data = temp->data;
delete temp;
unbalanced_node->left = l_child;
unbalanced_node->right = r_child;
}
//_ROTATION_END
//重载赋值运算符:中序遍历AVL树
template<class U>
ostream&operator<<(ostream&output, AVL<U>const&x) {
if (x.empty())return output;
stack<AVL<U>::NodePtr>S;
typename AVL<U>::NodePtr it = x.root;
while (it || !S.empty()) {
while (it) {
S.push(it);
it = it->left;
}
if (!S.empty()) {
output << S.top()->data << ' ';
it = S.top()->right;
S.pop();
}
}
return output;
}
//构造函数:置空根结点
template<class T>
AVL<T>::AVL() :_size(0), root(NULL) {
}
//析构函数:清空AVL树
template<class T>
AVL<T>::~AVL() {
clear();
}
//复制构造函数:先序遍历实现
template<class T>
AVL<T>::AVL(AVL<T> const&object) {
operator=(object);
}
//查找:中序遍历实现
template<class T>
int AVL<T>::find(T search_element)const {
if (empty())return EOF;
stack<NodePtr>S;
NodePtr it = root;
int position = 0;
while (it || !S.empty()) {
while (it) {
S.push(it);
it = it->left;
}
if (!S.empty()) {
if (S.top()->data == search_element)return position;
else position++;
it = S.top()->right;
S.pop();
}
}
return EOF;
}
//二分查找
template<class T>
bool AVL<T>::exist(T search_element)const {
if (empty())return false;
NodePtr it = root;
while (it) {
if (it->data == search_element)return true;
if (it->data > search_element)it = it->left;
else it = it->right;
}
return false;
}
//查找最大元素
template<class T>
T const&AVL<T>::max()const {
if (empty())return out_of_range;
NodePtr it = root;
while (it->right)it = it->right;
return it->data;
}
//查找最小元素
template<class T>
T const&AVL<T>::min()const {
if (empty())return out_of_range;
NodePtr it = root;
while (it->left)it = it->left;
return it->data;
}
//插入
template<class T>
void AVL<T>::insert(T insert_element) {
if (empty()) {
root = new TreeNode(insert_element);
return;
}
stack<NodePtr>S;
cirque<bool, 2>Q;
NodePtr it = root;
while (it->data != insert_element) {
S.push(it);
if (it->data > insert_element) {
if (!it->left) {
it->left = new TreeNode(insert_element);
_size++;
break;
}
else it = it->left;
}
else {
if (!it->right) {
it->right = new TreeNode(insert_element);
_size++;
break;
}
else it = it->right;
}
}
NodePtr last_node, this_node = it;
while (!S.empty()) {
last_node = this_node;
this_node = S.top();
S.pop();
Q.push(last_node == this_node->left ? true : false);
if (2 == Q.size())
if (!balanced(this_node)) {
if (Q.rear() && Q.front()) LeftLeftRotation(this_node);
else if (!Q.rear() && !Q.front()) RightRightRotation(this_node);
else if (Q.rear()) LeftRightRotation(this_node);
else RightLeftRotation(this_node);
break;
}
}
}
//删除
template<class T>
void AVL<T>::erase(T erase_element) {
if (empty())return;
stack<NodePtr>S;
auto it = root;
while (it) {
S.push(it);
if (erase_element < it->data)it = it->left;
else if (erase_element > it->data)it = it->right;
else if (!it->left && !it->right) {
S.pop();
if (it == root)root = NULL;
else if (it == S.top()->left)S.top()->left = NULL;
else S.top()->right = NULL;
delete it;
_size--;
break;
}
else if (!it->left&&it->right) {
it->data = it->right->data;
it->left = it->right->left;
NodePtr temp = it->right->right;
delete it->right;
it->right = temp;
break;
}
else if (it->left && !it->right) {
it->data = it->left->data;
it->right = it->left->right;
NodePtr temp = it->left->left;
delete it->left;
it->left = temp;
break;
}
else {
NodePtr finder = it;
it = it->left;
while (it) {
S.push(it);
it = it->right;
}
it = S.top();
finder->data = it->data;
if (!it->left && !it->right) {
S.pop();
if (it == S.top()->left)S.top()->left = NULL;
else S.top()->right = NULL;
delete it;
_size--;
break;
}
else if (!it->left&&it->right) {
it->data = it->right->data;
it->left = it->right->left;
NodePtr temp = it->right->right;
delete it->right;
it->right = temp;
break;
}
else {
it->data = it->left->data;
it->right = it->left->right;
NodePtr temp = it->left->left;
delete it->left;
it->left = temp;
break;
}
}
}
if (S.empty())return;
NodePtr last_node, this_node = S.top();
S.pop();
if (!balanced(this_node)) {
if (this_node->left)LeftLeftRotation(this_node);
else RightRightRotation(this_node);
return;
}
bool flag;
while (!S.empty()) {
last_node = this_node;
this_node = S.top();
S.pop();
flag = last_node == this_node->left ? true : false;
if (!balanced(this_node)) {
if (flag) LeftLeftRotation(this_node);
else RightRightRotation(this_node);
break;
}
}
}
//清空:后序遍历AVL树,释放所有结点
template<class T>
void AVL<T>::clear() {
_size = 0;
if (empty())return;
stack<NodePtr>S;
NodePtr it = root;
do {
while (it->left) {
S.push(it);
it = it->left;
}
if (it->right) {
S.push(it);
it = it->right;
}
else while (!S.empty()) {
while (it == S.top()->left && !S.top()->right ||
it == S.top()->right && !S.top()->left) {
delete it;
it = S.top();
S.pop();
if (S.empty()) {
delete it;
return;
}
}
if (it == S.top()->left) {
delete it;
it = S.top()->right;
break;
}
else {
delete it;
it = S.top();
S.pop();
if (S.empty()) {
delete it;
return;
}
}
}
} while (!S.empty());
root = NULL;
}
//树的结点数:先序遍历实现
template<class T>
inline int AVL<T>::size()const {
return _size;
}
//返回是否为空树
template<class T>
inline bool AVL<T>::empty()const {
return root ? false : true;
}
//_OPERATOR_BEGIN
//重载赋值运算符:先序遍历实现
template<class T>
void AVL<T>::operator=(AVL<T> const&another) {
clear();
if (another.empty())return;
stack<NodePtr>S;
NodePtr it = another.root;
while (it || !S.empty()) {
while (it) {
insert(it->data);
S.push(it);
it = it->left;
}
if (!S.empty()) {
it = S.top()->right;
S.pop();
}
}
}
//判断两棵AVL树是否相等:先序遍历实现
template<class T>
bool AVL<T>::operator==(AVL<T> const&another)const {
if (empty() ^ another.empty())return false;
if (empty() && another.empty())return true;
if (size() != another.size())return false;
stack<NodePtr>S;
NodePtr it = root;
while (it || !S.empty()) {
while (it) {
if (!another.exist(it->data))return false;
S.push(it);
it = it->left;
}
if (!S.empty()) {
it = S.top()->right;
S.pop();
}
}
return true;
}
//判断两棵AVL树是否不相等
template<class T>
bool AVL<T>::operator!=(AVL<T> const&another)const {
return operator==(another) ? false : true;
}
//_OPERATOR_END
_OC_END
#endif