我试图将0到11插入avl,然后按顺序删除4,5,6。我在rr_rotation函数中删除6时收到sigserv错误。这是我第一次实现avl而且我是编程新手。我哪里错了?我为自己的理解添加了一些注释,并跟踪错误发生的位置。这是我的代码:
#include<bits/stdc++.h>
using namespace std;
#define pow2(n) (1 << (n))
struct avl_node {
int data;
//int size;
struct avl_node *left;
struct avl_node *right;
}*root;
class avlTree {
public:
int height(avl_node *);
int diff(avl_node *);
avl_node *rr_rotation(avl_node *);
avl_node *ll_rotation(avl_node *);
avl_node *lr_rotation(avl_node *);
avl_node *rl_rotation(avl_node *);
avl_node* balance(avl_node *);
avl_node* insert(avl_node *, int);
int getBalance(avl_node*);
int getSize(avl_node*);
avl_node* minValueNode(avl_node*);
avl_node* del(avl_node *, int);
void inorder(avl_node *);
void preorder(avl_node *);
int kthsmallest(avl_node*, int);
avlTree() {
root = NULL;
}
};
int avlTree::height(avl_node *temp) {
int h = 0;
if (temp != NULL) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int max_height = max(l_height, r_height);
h = max_height + 1;
}
return h;
}
int avlTree::diff(avl_node *temp) {
int l_height = height(temp->left);
int r_height = height(temp->right);
int b_factor = l_height - r_height;
return b_factor;
}
avl_node *avlTree::rr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
if(temp == NULL)
cout<<"yes null 2"<<endl;
//cout<<"parent->right "<<temp->data<<endl;
parent->right = temp->left;
temp->left = parent;
cout<<"temp->left->data "<<temp->left->data<<endl;
return temp;
}
avl_node *avlTree::ll_rotation(avl_node *parent) {
avl_node *temp;
//cout<<"inside ll rotation"<<endl;
//cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = temp->right;
temp->right = parent;
return temp;
}
avl_node *avlTree::lr_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside lr rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->left;
parent->left = rr_rotation(temp);
return ll_rotation(parent);
}
avl_node *avlTree::rl_rotation(avl_node *parent) {
avl_node *temp;
cout<<"inside rl rotation"<<endl;
cout<<"parent = "<<parent->data<<endl;
temp = parent->right;
parent->right = ll_rotation(temp);
return rr_rotation(parent);
}
avl_node *avlTree::balance(avl_node *temp) {
int bal_factor = diff(temp);
if (bal_factor > 1) {
if (diff(temp->left) > 0)
temp = ll_rotation(temp);
else
temp = lr_rotation(temp);
} else if (bal_factor < -1) {
if (diff(temp->right) > 0)
temp = rl_rotation(temp);
else
temp = rr_rotation(temp);
}
return temp;
}
avl_node *avlTree::insert(avl_node *root, int value) {
//cout<<"Inside insert for val = "<<value<<endl;
if (root == NULL) {
root = new avl_node;
root->data = value;
root->left = NULL;
root->right = NULL;
return root;
} else if (value < root->data) {
root->left = insert(root->left, value);
root = balance(root);
} else if (value >= root->data) {
root->right = insert(root->right, value);
root = balance(root);
}
return root;
}
avl_node* avlTree::minValueNode(avl_node* node) {
avl_node* current = node;
while (current->left != NULL)
current = current->left;
return current;
}
int avlTree::getBalance(avl_node* N) {
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
avl_node* avlTree::del(avl_node *root, int value) {
cout<<"del for val = "<<value<<endl;
if (root == NULL){
cout<<"root is null here\n";
return root;
}
// If the key to be deleted is smaller than the
// root's key, then it lies in left subtree
if (value < root->data)
root->left = del(root->left, value);
// If the key to be deleted is greater than the
// root's key, then it lies in right subtree
else if (value > root->data)
root->right = del(root->right, value);
// if key is same as root's key, then This is
// the node to be deleted
else {
// node with only one child or no child
if ((root->left == NULL) || (root->right == NULL)) {
avl_node* temp = root->left ? root->left : root->right;
// No child case
if (temp == NULL) {
temp = root;
root = NULL;
cout<<"Root set to null\n";
}
else{
// One child case
cout<<temp->data<<" copied to root "<<root->data<<"\n";
*root = *temp;
// Copy the contents of
// the non-empty child
}
free(temp);
} else {
// node with two children: Get the inorder
// successor (smallest in the right subtree)
avl_node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node
root->data = temp->data;
// Delete the inorder successor
root->right = del(root->right, temp->data);
}
} // If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
//root->height = 1 + max(height(root->left),height(root->right));
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to
// check whether this node became unbalanced)
int balance = getBalance(root);
cout<<"balance = "<<balance<<" for root "<<root->data<<endl;
if(root->right == NULL)
cout<<"yes null"<<endl;
// If this node becomes unbalanced, then there are 4 cases// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0){
cout<<"balance1 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
avl_node* t = rr_rotation(root);
//root = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//rr_rotation(root);
}
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0) {
cout<<"balance2 = "<<getBalance(root->left)<<" for root "<<root->left->data<<endl;
cout<<"prev root "<<root->left->data<<endl;
//root->left = ll_rotation(root->left);
root = lr_rotation(root);
cout<<"new root "<<root->data<<endl;
//return rr_rotation(root);
return root;
} // Right Right Case
if (balance < -1 && getBalance(root->right) <= 0){
cout<<"balance3 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
avl_node* t = rr_rotation(root);
cout<<"Root of the modified sub-tree is "<<t->data<<endl;
return t;
//return ll_rotation(root);
}
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0) {
cout<<"balance4 = "<<getBalance(root->right)<<" for root "<<root->right->data<<endl;
//root->right = rr_rotation(root->right);
//return ll_rotation(root);
return rl_rotation(root);
}
return root;
}
void avlTree::inorder(avl_node *tree) {
if (tree == NULL)
return;
inorder(tree->left);
cout << tree->data << " ";
inorder(tree->right);
}
void avlTree::preorder(avl_node *tree) {
if (tree == NULL)
return;
cout << tree->data << " ";
preorder(tree->left);
preorder(tree->right);
}
int avlTree::getSize(avl_node* N){
if(N == NULL)
return 0;
return (getSize(N->left) + 1 + getSize(N->right));
}
int avlTree::kthsmallest(avl_node* N, int k){
int r = getSize(N->left) + 1;
if(k == r)
return N->data;
if(k < r)
return kthsmallest(N->left,k);
if(k > r)
return kthsmallest(N->right,k-r);
return -1;
}
int main(void) {
int n, i, x;
char s;
avlTree tree; for(i=0;i<12;i++){
root = tree.insert(root,i);
tree.preorder(root);
cout<<endl;
}
for(i=4;i<=6;i++){
root = tree.del(root,6);
tree.preorder(root);
cout<<endl;
}
return 0;
}