Skip to content
Snippets Groups Projects
Commit c75be6d8 authored by Romain Vuillemot's avatar Romain Vuillemot
Browse files

lab 8

parent fc9b329e
Branches
No related tags found
No related merge requests found
File added
%% Cell type:markdown id:a6a7c327 tags:
NAME:
%% Cell type:markdown id:e14a9e35-e497-4765-8089-95d0db59f82d tags:
# UE5 Fundamentals of Algorithms
# Lab 8: Binary trees traversals
%% Cell type:markdown id:da448b8a-05e3-4ee6-b3b8-6fa4c41f55b6 tags:
---
%% Cell type:markdown id:d3c4bf88-8101-42bb-a14d-9e5607b55d57 tags:
We will use the following binary tree data structure (unless specified otherwise):
%% Cell type:code id:2b179632-5d9e-4abd-95c1-abfea9d455df tags:
``` python
class Node:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
```
%% Cell type:markdown id:1d18a7cb-9003-4d84-a68d-dfbd8202713b tags:
## Exercise 1: Check if a binary tree is balanced
%% Cell type:markdown id:ac3a3e11-4a8d-416c-8b55-3c6a4137a457 tags:
Write an **iterative** function that checks if a binary tree is balanced, i.e. the difference between the heights of the left and right subtrees is at most 1.
Tips:
- Use af dfs traversal approach (using a stack) using a post-order approach (left, right, and root node)
- For each node, calculate and memorize the current height in a dictionnary
- Check if the current node is balanced, if not return `False`
- Mark the node as visited and store its height
- Return `True` if all the nodes are visited (without an un-balanced situation)
%% Cell type:code id:51a49306-6cb7-4e84-9257-081793657848 tags:
``` python
def is_balanced_ite(root):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:556f6692-1e4f-4f55-adbc-cf373402673d tags:
Compare to the following recursive version:
%% Cell type:code id:b7fb2e89-b045-4a46-851e-153c64e0de60 tags:
``` python
def get_height(node):
if node is None:
return -1
left_height = get_height(node.left)
right_height = get_height(node.right)
return max(left_height, right_height) + 1
def is_balanced(root):
# un abre vide (None) est équilibré
if root is None:
return True
return is_balanced(root.right) and is_balanced(root.left) and abs(get_height(root.left) - get_height(root.right)) <= 1
#get_height(racine)
#is_balanced(racine)
```
%% Cell type:markdown id:00e2ddec-e259-4f8b-a414-a11051672173 tags:
Write tests with both balanced and unbalanced trees.
%% Cell type:code id:f90da531-0173-429a-a415-923e7b2bf275 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:09013922-8606-4298-91e5-02da49a8ced2 tags:
## Exercise 2: DFS traversal orders
Given the following tree, which type of dfs traversal order you may use to return the number in ascending order?
```
1
/ \
2 5
/ \
3 4
```
%% Cell type:code id:afa39767-9b92-4eb7-8a2c-7b59715153da tags:
``` python
def inorder_traversal(root):
if root is not None:
inorder_traversal(root.left)
print(root.value, end=' ')
inorder_traversal(root.right)
```
%% Cell type:code id:e88833c1-3cf0-4751-bf79-d7ba410a3dd2 tags:
``` python
def preorder_traversal(root):
if root is not None:
print(root.value, end=' ')
preorder_traversal(root.left)
preorder_traversal(root.right)
```
%% Cell type:code id:fdff0e4c-e6f1-4185-b7dc-92aa3f8f7ccb tags:
``` python
def postorder_traversal(root):
if root is not None:
postorder_traversal(root.left)
postorder_traversal(root.right)
print(root.value, end=' ')
```
%% Cell type:code id:78fbbaa9-a66f-4edc-ad6d-35364efcf83a tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:0ab0e8cb-0f07-4df4-a1e1-8934b9fa9de2 tags:
Now write the corresponding tree for the 2 other traversal functions to return values in ascending order (i.e. provide a new tree but do not change the functions)
%% Cell type:code id:498cd602-5e9e-456b-b66a-4b289442170f tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:13dd6b6f-e843-4a92-af0e-2c860d95cf40 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:098f76aa-1597-4394-a7d7-564e5e1949cf tags:
## Exercise 3: Check if two binary trees are identical
```
1 1
/ \ / \
2 3 2 3
```
For the example above, it may return `True`
%% Cell type:code id:49aa6fce-c267-4ac1-af06-085ab33cfb4f tags:
``` python
def check_equal(p, q):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:d34397b0-e505-410f-9edb-75d6f9f35b32 tags:
``` python
p = Node(1)
q = Node(1)
assert check_equal(p, q)
```
%% Cell type:markdown id:8d65c14b tags:
## Exercise 4: Check if a binary tree has a cycle
Write a function to determine if a binary tree contains a cycle (i.e. when a node is revisited during traversal).
%% Cell type:code id:3e5a8a2d tags:
``` python
def has_cycle(node, visited=None, parent=None):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:83f55a68 tags:
``` python
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
assert not has_cycle(root)
# add a cycle
root.left.left.right = root
assert has_cycle(root)
```
%% Cell type:markdown id:1aa5b552-aaa6-4f97-921e-fcc0135ad485 tags:
## Exercise 5: Check if a binary tree is connected
Write a function to determine if a binary is connected to all the nodes of the tree. Warning: will now use a dictionnary data structure to store the tree.
%% Cell type:code id:8ba8a250-70f7-4ec8-9deb-eea0b3f34ca3 tags:
``` python
T_dict = {
'0': ['1', '2'],
'1': ['4', '5'],
'2': ['3'],
'4': [],
'5': [],
'3': []
}
```
%% Cell type:code id:0460d5e5-d9b1-4418-a58b-0e00a481ed67 tags:
``` python
def is_connected(T_dict):
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:d8298892-488a-482c-98bd-2a16d02f29a6 tags:
Write tests for bot a connected and a non-connected tree.
%% Cell type:code id:55ab4951-be83-48ee-a6c5-85d6e73bdf05 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:markdown id:c06c33fb-661b-4a73-84f7-c19c5c157fae tags:
## Exercise 6: Calculate the diameter of a binary tree
To find the diameter of a binary tree, you need to compute the longest path between any two nodes in the tree. This path may or may not pass through the root. Here is a way to calculate the diameter:
1. Calculate the height of the left and right subtrees for each node
2. Calculate the diameter at each node as the height of left subtree + right subtree
3. Traverse the tree and keep track of the max diameter encountered
Note: we will used the `Node` data structure.
%% Cell type:code id:c2595aa9-d477-48c8-9aaa-9bc331930877 tags:
``` python
# YOUR CODE HERE
raise NotImplementedError()
```
%% Cell type:code id:e21f200a-ff9b-46af-b504-876c47b80f48 tags:
``` python
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
assert diameter(root) == 3 # 3
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment