Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I wrote an AVL tree, I'm sure that it works correctly, but my vertex counting does not work for the subtree. Help find a mistake.
I count the number of vertices only in the field: "kol".

Here is my code:

C++
#include <cmath>
#include <assert.h>

using namespace std;

class Node
{
public:
    int key;
    Node *left;
    Node *right;
    int height;
    int kol;
};

int max(int a, int b);

int height(Node *N){
    if(N == nullptr)
        return 0;
    return N->height;
}

int max(int a, int b){
    return (a > b)? a : b;
}

Node* newNode(int key){
    Node* node = new Node();
    node->key = key;
    node->left = nullptr;
    node->right = nullptr;
    node->height = 1;
    node->kol = 1;


    return node;
}

Node * rightRotate(Node *y){



    Node *x = y->left;
    Node *T2  = x->right;


    x->right = y;
    y->left = T2;

    if (y->left == nullptr && y->right == nullptr) y->kol = 1;
    else
    if (y->left == nullptr) y->kol = y->right->kol + 1;
    else
    if (y->right == nullptr) y->kol = y->left->kol + 1;
    else
        y->kol = y->right->kol + y->left->kol + 1;

    if (x->left == nullptr && x->right == nullptr) x->kol = 1;
    else
    if (x->left == nullptr) x->kol = x->right->kol + 1;
    else
    if (x->right == nullptr) x->kol = x->left->kol + 1;
    else
        x->kol = x->right->kol + x->left->kol + 1;



    y->height = max(height(y->left), height(y->right)) + 1;
    x->height = max(height(x->left), height(x->right)) + 1;

    return x;
}

Node * leftRotate(Node *x){

    Node *y = x->right;
    Node *T2 = y->left;

    y->left = x;
    x->right = T2;


    if (x->left == nullptr && x->right == nullptr) x->kol = 1;
    else
    if (x->left == nullptr) x->kol = x->right->kol + 1;
    else
    if (x->right == nullptr) x->kol = x->left->kol + 1;
    else
    x->kol = x->right->kol + x->left->kol + 1;

    if (y->left == nullptr && y->right == nullptr) y->kol = 1;
    else
    if (y->left == nullptr) y->kol = y->right->kol + 1;
    else
    if (y->right == nullptr) y->kol = y->left->kol + 1;
    else
    y->kol = y->right->kol + y->left->kol + 1;

    x->height = max(height(x->left), height(x->right)) + 1;
    y->height = max(height(y->left), height(y->right)) + 1;


    return y;
}

int getBalance(Node *N){
    if (N == nullptr)
        return 0;
    return height(N->left) - height(N->right);
}

Node* insert(Node* node, int key){
    if (node == nullptr)
        return (newNode(key));

    //node->kol++;
    if(key < node->key){
        node->left = insert(node->left, key);
        node->kol += 1;
    }
    else if (key > node->key){
        node->right = insert(node->right, key);
        node->kol += 1;
    }

    else {
        return node;
    }
    node->height = 1 + max(height(node->left), height(node->right));


    int balance = getBalance(node);

    //left left
    if (balance > 1 && key < node->left->key)
        return rightRotate(node);

    //right right
    if (balance < -1 && key > node->right->key)
        return leftRotate(node);

    // left right
    if (balance > 1 && key > node->left->key){
        node->left = leftRotate(node->left);
        return rightRotate(node);
    }

    //right left
    if (balance < -1 && key < node->right->key){
        node->right = rightRotate(node->right);
        return  leftRotate(node);
    }


    return node;
}

Node* minValueNode(Node* node){
    Node* current = node;

    while (current->left != nullptr)
        current = current->left;

    return  current;
}

Node* deleteNode(Node* root, int key)
{
    if (root == NULL)
        return root;

    if ( key < root->key ){
        root->left = deleteNode(root->left, key);
        root->kol--;
    }


    else if( key > root->key ){
        root->right = deleteNode(root->right, key);
        root->kol--;
    }


    else
    {

        if( (root->left == NULL) ||
            (root->right == NULL) )
        {

            Node *temp = root->left ?
                         root->left :
                         root->right;

            // No child case
            if (temp == NULL)
            {
                temp = root;
                root = NULL;
            }
            else
            {
                int t = root->kol;
//                cout << -1;
                *root = *temp;
                root->kol = t - 1;
            }

            free(temp);
        }
        else
        {

            Node* temp = minValueNode(root->right);

            root->key = temp->key;
            //root->kol = temp->kol;


            root->right = deleteNode(root->right,
                                     temp->key);
        }
    }

    // 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);

    // If this node becomes unbalanced,
    // then there are 4 cases

    // Left Left Case
    if (balance > 1 &&
        getBalance(root->left) >= 0)
        return rightRotate(root);

    // Left Right Case
    if (balance > 1 &&
        getBalance(root->left) < 0)
    {
        root->left = leftRotate(root->left);
        return rightRotate(root);
    }

    // Right Right Case
    if (balance < -1 &&
        getBalance(root->right) <= 0)
        return leftRotate(root);

    // Right Left Case
    if (balance < -1 &&
        getBalance(root->right) > 0)
    {
        root->right = rightRotate(root->right);
        return leftRotate(root);
    }

    return root;
}


void preOrder(Node* root){
    if(root != nullptr){
        preOrder(root->right);
        cout << root->key << " ";
        preOrder(root->left);

    }
}

int KMin(Node* root, int k){
    int rsize = root->right ? root->right->kol : 0;

    if (k < rsize + 1)
        return KMin(root->right, k);

    if (k > rsize + 1)
        return KMin(root->left, k - 1 - rsize);

    return root->key;


/*
    if (root){
        if (root->right) {
            if (k < root->right->kol + 1) {
                return KMin(root->right, k);
            } else if (k > root->right->kol + 1) {
                return KMin(root->left, k - root->right->kol - 1);
            } else if (k == root->right->kol + 1)
                return root->key;
        } else
        {
            if (k == 1) return root->key;
            //if (k == root->kol) cout << root->key << "\n";
            return KMin(root->left, k - 1);
        }
    }


    return -1;
*/
}

int main(){

    Node *root = NULL;

    int n = 0;
    int type = 0;
    int number = 0;

    cin >> n;

    for (int i = 0; i < n; ++i) {
        cin >> type >> number;
        //cout << type << " ";
        if (type == 1){
            root = insert(root, number);
        }
        if (type == 0){
           cout << KMin(root, number) << endl;
        }
        if (type == -1){
            root = deleteNode(root, number);
        }
    }


What I have tried:

I wrote an AVL tree, but my vertex counting does not work for the subtree.
Posted
Updated 1-Apr-20 21:13pm

Quote:
I wrote an AVL tree, I'm sure that it works correctly, but my vertex counting does not work for the subtree. Help find a mistake.

As programmer, your job is to build bug free programs (as much as possible).
So you need to learn to debug your code yourself, the tool of choice is the debugger.
-----
Your code do not behave the way you expect, or you don't understand why !

There is an almost universal solution: Run your code on debugger step by step, inspect variables.
The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't know what your code is supposed to do, it don't find bugs, it just help you to by showing you what is going on. When the code don't do what is expected, you are close to a bug.
To see what your code is doing: Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute.

Debugger - Wikipedia, the free encyclopedia[^]

Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]
Basic Debugging with Visual Studio 2010 - YouTube[^]

1.11 — Debugging your program (stepping and breakpoints) | Learn C++[^]

The debugger is here to only show you what your code is doing and your task is to compare with what it should do.
 
Share this answer
 
It's been decades I last touched any tree code, so maybe I'm missing something obvious. But:

The balancing part in the insert function looks wrong: you're comparing the key of the new node against the keys of its children. But since you make sure to always order your insertions by key, it is already predetermined that the keys in the left branch are always smaller, and the keys in the right branch are always greater, after insertion. If you're trying to balance, why are you looking at the keys - shouldn't you be looking at the counts?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900