需要注意的是删除结点,有时删除结点不会影响此结点所在层的平衡,如删除50,会在递归返回时判断出40的平衡受影响
当删除30时,用31补充。30所在层的平衡已经被破坏,需要马上调整。删除40也是
40
30 70
20 31 50
19
template<class T>
struct BinTree
{
T data;
BinTree* left, * right;
//BinTree* parent;
int height;
BinTree(T e, int h = 1, BinTree* l = nullptr, BinTree* r = nullptr, BinTree* p = nullptr) :data(e) {
left = l;
right = r;
//parent = p;
height = h;
}
};
template<class T>
class AVL {
typedef BinTree<T> BTNode;
//typedef BinTree<T> node_type;
//typedef T elem_type;
public:
BTNode* m_root;
AVL() :m_root(nullptr){}//初始化为空树
~AVL() {
destruct(m_root); m_root = nullptr;
}
void destruct(BTNode* T) {
if (T != nullptr) {
destruct(T->left);
destruct(T->right);
//cout << "destruct= " << T->data << endl;
delete T;
}
}
BTNode* find(T e) {
if (m_root == nullptr)return nullptr;
BTNode* root = m_root;
while (root) {
if (root->data == e)return root;
else if (e > root->data)root = root->right;
else root = root->left;
}
return nullptr;
}
void insert(T e) {
//cout << "insert= " << e << endl;
//my_preOrder(m_root); cout << endl;
//my_inOrder(m_root); cout << endl;
//my_floorOrder(m_root); cout << endl;
m_root = insert(m_root, e);
}
void remove(T e) {
//cout << "remove= " << e << endl;
m_root = remove(m_root, e);
//cout << "remove, end" << endl; cout << endl;
}
private:
BTNode* insert(BTNode* root, T e) {//经过平衡调整后结点可能会变,因此递归返回指针
if (root ==nullptr) {//空树
root = new BTNode(e);
return root;
}
if (e == root->data)return root;
else if (e < root->data) root->left = insert(root->left, e);
else root->right = insert(root->right, e);
root->height = max(getheight(root->left), getheight(root->right)) + 1;//重新计算高度
root = adjustBanlence(root);//调整
return root;
}
BTNode* adjustBanlence(BTNode* root) {//检查平衡因子并调整
if(root==nullptr) return nullptr;
int bf = getheight(root->left) - getheight(root->right), bff;
if (bf > 1) {//左子树高
//cout << "adjustBanlence= " << root->data << endl;
bff = getheight(root->left->left) - getheight(root->left->right);//判断是ll还是lr
if (bff >= 0) return ll_rotate(root);//高度相同也采用ll
else return lr_rotate(root);
}
else if (bf < -1) {//右子树高
//cout << "adjustBanlence= " << root->data << endl;
bff = getheight(root->right->left) - getheight(root->right->right);
if (bff > 0) return rl_rotate(root);
else return rr_rotate(root);//高度相同也采用rr
}
return root;//不用调
}
BTNode* remove(BTNode* root, T e) {
if (root == nullptr)return nullptr;//结点不存在
if (e < root->data) {
root->left = remove(root->left, e);//递归查找
}
else if (e > root->data) {
root->right = remove(root->right, e);
}
else {//找到目标结点
if (root->left == nullptr || root->right == nullptr) {//只有一棵子树
BTNode* temp = root->right ? root->right : root->left;
delete root;
root = temp;
return root;
}
else {//有左右子树
BTNode* temp = getMinNode(root->right);
root->data = temp->data;//用右子树中的最小结点代替
root->right = remove(root->right, temp->data);//删除替代的结点
}
}
//删除完马上检查
root->height = max(getheight(root->left), getheight(root->right)) + 1;//删除操作完了,重新计算高度
root = adjustBanlence(root);//调整
return root;
}
BTNode* getMinNode(BTNode* root) {
if (root == nullptr)return nullptr;
while (root->left)root = root->left;
return root;
}
bool is_leaf(BTNode* node) {
if (node->left == node->right == nullptr)return true;
else return false;
}
int getheight(BTNode* node) {
if (node == nullptr)return 0;
else return node->height;
}
BTNode* ll_rotate(BTNode* y) {
if (y == nullptr) return nullptr;
//cout << "ll_rotate= " << y->data << endl;
BTNode* x = y->left;
y->left = x->right;
x->right = y;
y->height = max(getheight(y->left), getheight(y->right)) + 1;
x->height = max(getheight(x->left), getheight(x->right)) + 1;
return x;
}
BTNode* rr_rotate(BTNode* y) {
if (y == nullptr)return nullptr;
//cout << "rr_rotate= " << y->data << endl;
BTNode* x = y->right;
y->right = x->left;
x->left = y;
y->height = max(getheight(y->left), getheight(y->right)) + 1;
x->height = max(getheight(x->left), getheight(x->right)) + 1;
return x;
}
BTNode* lr_rotate(BTNode* T) {
if (T == nullptr)return nullptr;
//cout << "lr_rotate= " << T->data << endl;
T->left = rr_rotate(T->left);
return ll_rotate(T);
}
BTNode* rl_rotate(BTNode* T) {
if (T == nullptr)return nullptr;
//cout << "rl_rotate= " << T->data << endl;
T->right = ll_rotate(T->right);
return rr_rotate(T);
}
};
void my_inOrder(const BinTree<int>* root) {
if (root) {
my_inOrder(root->left);
cout << root->data << ' ';
my_inOrder(root->right);
}
}
void my_preOrder(const BinTree<int>* root) {
if (root) {
cout << root->data << ' ';
my_preOrder(root->left);
my_preOrder(root->right);
}
}
void my_floorOrder( BinTree<int>* root) {
if (root == nullptr) return;
queue<BinTree<int>* > q;
q.push(root);
int a = 1, b;
while (!q.empty()) {
b = 0;//记录每层有多少个结点
for (int i = 0; i < a; i++) {
if (q.front()->left) {
q.push(q.front()->left); b++;
}
if (q.front()->right) {
q.push(q.front()->right); b++;
}
cout << q.front()->data << ' ';
q.pop();
}
cout << ',';
a = b;
}
cout << endl;
}
void test02() {
//sizeof(a) / sizeof(*a)
int a3[] = { 49,38,65,97,76,13,27,49 };
int a7[] = { 15,1,2,3,5,8,4,9,6,7 };
int a2[] = { 1,2,3,4,5,7,8,9,10,6 };
int a4[] = { 1,2,3,4,5,7,8,9,10,6 };
int a6[] = { 8,3,6,4,2,1,5,7,9,10,12,11 };
int a9[] = { 16,9,20,15,3,18,13,2,17,10,5,7,11,12,6,1,19,4,8,14 };
int a8[] = { 53,17,78,9,45,65,87,32 };
int a5[] = { 53, 3, 542, 748, 14, 214, 154, 63, 616 };
int a[] = { 20,30,40,50,70,31,19,60 };
AVL<int> avl; for (const int i : a)avl.insert(i);
avl.remove(60);
avl.remove(40);
//avl.remove(60);
//avl.remove(30);
my_preOrder(avl.m_root); cout << endl;
my_inOrder(avl.m_root); cout << endl;
my_floorOrder(avl.m_root); cout << endl;
}