实施avl的问题

时间:2017-08-10 18:54:59

标签: c++ data-structures avl-tree

我试图将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;
}

0 个答案:

没有答案