当Node的高度不是-1,0或1时,这个avl实现应该执行旋转,我不知道为什么旋转不起作用。
我也认为calcHeight func没有正确实现。有什么建议吗?
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node *parent, *left, *right;
int height;
Node(int x)
{
data = x;
left = NULL;
right = NULL;
parent = NULL;
height = -1;
}
};
class AvlTree {
private:
Node *root;
public:
AvlTree() { root = NULL; }
bool Find(int x) {
return find(x, root);
}
bool find(int x, Node *p) {
if (p == NULL) return false;
if (x == p->data) return true;
if (x < p->data) return find(x, p->left);
find(x, p->right);
}
void Insert(int x) {
root = insert(x, root);
root = Balance(root);
}
//Node *AssignParent(Node *p, Node *q){
// if (q->left == p || q->right==p)
// p->parent = q;
// return p;
// return NULL;
//}
Node *insert(int x, Node *p) {
if (p == NULL)
return new Node(x);
if (x<p->data)
p->left=insert(x, p->left);
else if (x>p->data)
p->right=insert(x, p->right);
else
throw "exception";
return p;
}
void Remove(int x) {
root = remove(x, root);
}
Node *remove(int x, Node *p) {
if (p == NULL)
throw "exception";
if (x<p->data)
p->left = remove(x, p->left);
else if (x>p->data)
p->right = remove(x, p->right);
else if (p->right == NULL)
p = p->left;
else if (p->left == NULL)
p = p->right;
else { // node p has two children
p->data = findMin(p->right); // successor of x
p->right = remove(p->data, p->right);
}
return p;
}
int findMin(Node *p) {
if (p->left == NULL) return p->data;
return findMin(p->left);
}
void Preorder(AvlTree b){
preorder(b.root);
}
void preorder(Node *p){
if (p == NULL)
return;
cout << p->data << endl;
preorder(p->left);
preorder(p->right);
}
Node *leftRotate(Node *B){
if (B == NULL)
throw "exception";
Node *p = B->parent;
Node *D = B->right;
if (D == NULL)
throw "exception";
D->parent = p;
if (p == NULL)
root = D;
else if (p->left == B)
p->left = D;
else if (p->right = B)
p->right = D;
B->right = D->left;
if (B->right != NULL)
B->right->parent = B;
D->left = B;
B->parent = D;
return D;
}
Node *rightRotate(Node *D){
if (D == NULL)
throw "exception";
Node *p = D->parent;
Node *B = D->left;
if (B == NULL)
throw "exception";
B->parent = p;
if (p == NULL)
root = B;
else if (p->left == D)
p->left = B;
else if (p->right == D)
p->right = B;
D->left = B->right;
if (D->left != NULL)
D->left->parent = D;
D->parent = B;
B->right = D;
return B;
}
Node *leftRightRotate(Node *D){
Node *B = D->left;
D->left = leftRotate(B);
return rightRotate(D);
}
Node *rightLeftRotate(Node *B){
Node *D = B->right;
B->right = rightRotate(D);
return leftRotate(B);
}
int Max(int a, int b){
return a > b ? a : b;
}
int CalcHeight(Node *p){
if (p == NULL)
return -1;
int hl = CalcHeight(p->left);
int hr = CalcHeight(p->right);
p->height = 1 + Max(hl, hr);
return p->height;
}
int diff(Node *p){
return CalcHeight(p->left) - CalcHeight(p->right);
}
Node *Balance(Node *p){
if (diff(p) > 1){
if (diff(p->left) > 0){
return rightRotate(p);
}
else
{
return leftRightRotate(p);
}
}
else if (diff(p) < -1){
if (diff(p->right)>0){
return leftRotate(p);
}
else{
return rightLeftRotate(p);
}
}
return p;
}
};
void main(){
int x;
AvlTree t;
t.Insert(57);
t.Insert(28);
t.Insert(83);
t.Insert(15);
t.Insert(40);
t.Insert(94);
t.Insert(71);
t.Insert(77);
t.Insert(9);
t.Insert(100);
t.Insert(62);
t.Insert(52);
t.Insert(36);
t.Insert(68);
t.Insert(45);
t.Preorder(t);
cin >> x;
};