---
# System prepended metadata

title: 'Week 10 - Self-balancing [Trees]'

---

# Week 10 - Self-balancing [Trees]
 

## Team

Team name: **Group [497441]**
Date: 05/12/2021

Members: Max Thielen

| Role | Name |
|   -  |   -  |
| **Facilitator** keeps track of time, assigns tasks and makes sure all the group members are heard and that decisions are agreed upon.                 |   Max Thielen   |
| **Spokesperson** communicates group’s questions and problems to the teacher and talks to other teams; presents the group’s findings.             |   Max Thielen   |
| **Reflector** observes and assesses the interactions and performance among team members. Provides positive feedback and intervenes with suggestions to improve groups’ processes.                                                  |   Max Thielen   |
| **Recorder** guides consensus building in the group by recording answers to questions. Collects important information and data.                        |   Max Thielen   |

## Activities

### Activity 1: Time complexity
* **How many levels does the tree have? Give a formula that gives the minimum number of levels in case the tree has n values.**

The minimum number of levels to a tree with n nodes is calculated by taking the greatest integer less than or equal to log(n) otherwise know as **floor(log(n))**.
* **What is the worst-case time complexity of removal and membership testing in a tree where the number of levels is kept as low as possible?**

The worst case time complexity of a rebalancing binary tree can be represented as **O(log(n))**.

### Activity 2: A naive approach
```c=
int height(const bintree_node* node) {
    if (node == nullptr)
        return -1;
    else
        return std::max(height(node->left()), height(node>right())) + 1;
}
```
* **How many nodes does the function visit?**

The Height function visits all node in the tree is called with the root node.
* **What is the time complexity of the height function give above? Give your answer in Big O notation.**

O(n)


### Activity 3: Remembering tree heights
```c=
void bintree_node::update_height() {
    // failed recursive approach
    // if(m_parent!= nullptr) {
    //     m_parent->m_height++;
    //     m_parent->update_height();
    // }
    
    if(m_right == nullptr && m_left == nullptr){
        m_height = 0;
    }
    else if(m_right == nullptr) {
        m_height = std::max(-1, m_left->m_height)+1;
    }
    else if(m_left == nullptr) {
        m_height = std::max(-1, m_right->m_height)+1;
    }
    else {
        m_height = std::max(m_right->m_height, m_left->m_height)+1;
    }
}
```
### Activity 4: Do it yourself: Balance factors

![](https://i.imgur.com/ubCDAYB.png)
![](https://i.imgur.com/AiZI980.png)


### Activity 5: Computing the balance factor
```c=
int bintree_node::balance() const {
    if(this == nullptr){
        //std::cout<<"pooo ... disgrace"<<'\n';
        return 0;
    }
    else{
        //std::cout << m_value << '\n';
        if (m_right == nullptr && m_left == nullptr) return 0;
        else if (m_right == nullptr) {
            m_left->update_height();
            return (m_left->m_height);
        } else if (m_left == nullptr) {
            m_right->update_height();
            return (m_right->m_height);
        } else if (m_right != nullptr && m_left != nullptr) {
            m_right->update_height();
            m_left->update_height();
            return (m_right->m_height - m_left->m_height);
        } else return 0;
    }
}
```

### Activity 6: Balancing acts

![](https://i.imgur.com/wVqopCU.png)
Assuming Tree (a) was build correctly, Tree (b) is also correct since C>D in Tree (a) however, C is located in the left subtree with D being the root.

Tree ( c) is built correctly as well. Node D and C are correctly swapped, since D is the maximum node in the left subtree. (replacing the root node)

Lastly, Tree (d) is incorrect varient of Tree (a). The only difference from Tree ( c) is that D and A are swapped. This is a illegal switch since A is still less than D however, A is placed as the right left node of D.

### Activity 7: Implement left rotation
```c=
void bintree_node::rotate_left() {
    auto r = m_right;
    auto rl = m_right->m_left;
    auto parent = m_parent;

    m_right->set_left(this);
    set_right(rl);
    parent->replace_child(this, r);

    update_height();
    r->update_height();
}
```

### Activity 8: Implement right rotation
```c=
void bintree_node::rotate_right() {
    auto l = m_left;
    auto lr = m_left->m_right;
    auto parent = m_parent;

    m_left->set_right(this);
    set_left(lr);
    parent->replace_child(this, l);

    update_height();
    l->update_height();
}
```

### Activity 9: Left rotations and balance
![](https://i.imgur.com/On000Y4.png)


### Activity 10: Right rotations and balance
![](https://i.imgur.com/pCDqpYY.png)


### Activity 11: Fixing right-heavy trees using rotation combos
In a right-heavy unbalanced (sub)tree, the (root) node has a balance factor of +2. There are
three cases to consider: the balance factor of the node’s right child can be either -1, 0, or +1
* **For which of the three cases do we need to perform a right-left rotation?**

If the right child has a balance factor of (-1), LR rotation is required to restore the tree's balance. 

* **For the case where an RL rotation is applied, what are the possible balance factors of the tree after the RL rotation?**

After LR rotation the tree should be perfectly blanced assuming the three was balanced further down before the rotation was applied. 
* **For the cases where only a left rotation is applied, what are the possible balance factors of the tree after the left rotation?**

If the right child has a balance factor of (+1), solely rotating left will perfectly blance the tree. Howevere, if the right child has a balance factor of (0), the final balance factor of the tree ends up being (-1).

### Activity 12: Fixing left-heavy trees using rotation combos
The balance factor of the node’s left child can be either -1, 0, or +1, again giving three cases to
consider.
* **For which of the three cases do we need to perform a left-right rotation?**

If the left child has a balance factor of (+1), RL rotation is required to restore the tree's balance. 
* **For the case where an LR rotation is applied, what are the possible balance factors of the tree after that rotation combo?**

After RL rotation the tree should be perfectly blanced assuming the three was balanced further down before the rotation was applied.
* **For the cases where only a right rotation is applied, what are the possible balance factors of the tree after the rotation?**

If the left child has a balance factor of (-1), solely rotating right will perfectly blance the tree. Howevere, if the left child has a balance factor of (0), the final balance factor of the tree ends up being (+1).

### Activity 13: Rebalancing the tree
```c=
void bintree_node::fix_left_heavy() {
    switch (m_left->balance()) {
        case 0:
            rotate_right();
        case -1:
            rotate_right();
        case +1:
            m_left->rotate_left();
            rotate_right();
            break;
    }
}

void bintree_node::fix_right_heavy() {
    switch (m_right->balance()) {
        case 0:
            rotate_left();
        case +1:
            rotate_left();
        case -1:
            m_right->rotate_right();
            rotate_left();
            break;
    }
}
```
## Look back

### What we've learnt

Although AVL tree operations are quite complex, the operations are rather logical after working through them and do improve the efficiency of a tree data structure dramaticly.

### What were the surprises

Not in particular.

### What problems we've encountered

How difficult it was to think about tree rotation and balance factors.

### What was or still is unclear

How can a node of a height of H-1?

### How did the group perform?

Frictionless.



