0% found this document useful (0 votes)
2 views19 pages

day2 srm

The document provides an introduction to non-linear data structures, specifically focusing on trees, which are hierarchical structures made up of nodes connected by edges. It explains key properties, terminology, types of trees, and various tree traversal methods, including depth-first and level-order traversals. Additionally, it covers concepts like the height and diameter of a binary tree, along with Python code examples for better understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views19 pages

day2 srm

The document provides an introduction to non-linear data structures, specifically focusing on trees, which are hierarchical structures made up of nodes connected by edges. It explains key properties, terminology, types of trees, and various tree traversal methods, including depth-first and level-order traversals. Additionally, it covers concepts like the height and diameter of a binary tree, along with Python code examples for better understanding.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 19

Introduction to Non-Linear Data Structures

"Before we dive into Trees, let's quickly recall Data Structures. We have Linear Data Structures like
Arrays, Linked Lists, Stacks, and Queues. But what if we need something more flexible? This is where
Non-Linear Data Structures come into play."

"Can anyone guess where we use hierarchical structures in real life?"

(family trees, file systems, organization structures, etc.)

"Great! In non-linear structures, elements are not stored sequentially. Instead, they maintain
hierarchical relationships. Two key types are Trees and Graphs. Today, we will focus on Trees, one of
the most powerful data structures used in computing."

Introduction to Trees

"A Tree is a hierarchical data structure made up of nodes connected by edges. Unlike a linked list,
where each element points to the next, trees branch out like a real tree."

Example: "Imagine your computer's file system. The root directory contains multiple folders, and
each folder can contain files or subfolders. This structure follows a tree-like pattern."

Key Properties of Trees:

 A tree has a root node (top-most node)

 Each node can have child nodes

 A node without children is called a leaf node

 Trees don't contain cycles (i.e., no circular references)

"Let's visualize a simple family tree. Can someone give an example of a hierarchical relationship in
their family or workplace?"

Example (Draw on the board):


"Think about your computer’s file system."

Draw this structure on the board:

Root (C:/)

├── Documents

│ ├── Resume.docx

│ ├── Notes.txt

├── Pictures

│ ├── Photo1.jpg

│ ├── Photo2.png
Explain:

 C:/ is the Root Node

 Documents and Pictures are child nodes of C: They contain more files (subnodes).

 Resume.docx and Notes.txt are Leaf Nodes (No children).

 No cycles exist (A file doesn’t point back to its parent folder).

"Can you think of other real-life examples where data is stored in a tree structure?"
(Expected answers: Family Tree, Organization Chart, DOM in HTML, etc.)

Tree Terminology

"Now that we know what trees are, let’s understand some important terms used in tree data
structures."

Term Definition

Root Node The top-most node in the tree

Parent Node A node that has one or more child nodes

Child Node A node derived from another node

Leaf Node A node with no children

Sibling Nodes Nodes that share the same parent

Edge The connection between two nodes

Depth of a Node Distance from the root to that node

Height of a Tree Longest path from the root to a leaf

Interactive Example:

"Let’s draw a simple tree and label the Root, Parent, Child, and Leaf Nodes."

(Show the following tree on the board and ask students to identify components.)

A (Root)

/ \

B C

/\ / \

D E F G

Ask: "What is the root node? What are the leaf nodes? What are the siblings?”

Types of Trees
 General
 Binary
 Ternary
 N-ary

Types of Binary Trees

1. Full Binary Tree A full Binary tree is a special type of binary tree in which every parent
node/internal node has either two or no children.

2. Perfect Binary Tree A perfect binary tree is a type of binary tree in which every internal node
has exactly two child nodes and all the leaf nodes are at the same level.

3. Complete Binary Tree A complete binary tree is just like a full binary tree, but with two
major differences. Every level must be completely filled. All the leaf elements must lean
towards the left. The last leaf element might not have a right sibling i.e. a complete binary
tree doesn't have to be a full binary tree.

4. Balanced Binary Tree It is a type of binary tree in which the difference between the
height of the left and the right subtree for each node is either 0 or 1.
Binary Trees & Their Properties A Binary Tree is a tree in which each node has at most two children.
This makes it easier to implement and traverse.

"A binary tree restricts each node to ≤ 2 children—left and right."

Whiteboard Binary Tree:

10

/ \

5 20

/\

3 7

Properties of a Binary Tree:

1. Each node has at most two children (left and right).

2. Maximum number of nodes at level 'L' = 2^L.

3. Height of a balanced tree with 'N' nodes = log(N).

Types of Binary Trees:

 Full Binary Tree: Every node has either 0 or 2 children.

 Complete Binary Tree: All levels are completely filled except possibly the last.

 Perfect Binary Tree: A full tree where all leaf nodes are at the same level.

 Balanced Binary Tree: The height difference between left and right subtrees is at most 1.

Let's go step by step and visualize how the binary tree is built using the given Python code.

Understanding the Code Line by Line

Step 1: Define a TreeNode class

class TreeNode:

def __init__(self, val):

self.val = val

self.left = None

self.right = None

 This defines a TreeNode class.

 Each node stores:

o val → The value of the node.


o left → A reference to the left child (initially None).

o right → A reference to the right child (initially None).

Step 2: Function to Insert Nodes

def insert_node(root, val):

 This function inserts a new node into the binary tree.

 root → The current node of the tree.

 val → The value to insert.

Step 3: Base Case - If the tree is empty

if not root:

return TreeNode(val)

 If there is no tree (i.e., root is None), we create a new node with the given val and return it.

Step 4: Insert Left Child If Possible

if not root.left:

root.left = TreeNode(val)

 If the left child of the current node is empty, insert the new value there.

Step 5: Insert Right Child If Left is Occupied

elif not root.right:

root.right = TreeNode(val)

 If the left child is already occupied, check the right child.

 If it's empty, insert the new value here.

Step 6: If Both Left & Right Are Full, Insert in Left Subtree Recursively

else:

root.left = insert_node(root.left, val)

 If both left and right children exist, we recursively try inserting into the left subtree.

Step 7: Return the Updated Root


return root

 Finally, return the updated root of the tree.

Visual Representation

Let’s insert values in the order: 10, 20, 30, 40, 50, 60, 70, 80, 90, 100.

1️⃣ Insert 10 (Tree is empty, so it becomes root)

10

2️⃣ Insert 20 (Goes to the left of 10)

10

20

3️⃣ Insert 30 (Goes to the right of 10)

10

/ \

20 30

4️⃣ Insert 40 (Left of 20)

10

/ \

20 30

40

5️⃣ Insert 50 (Right of 20)

10

/ \

20 30

/ \

40 50
6️⃣ Insert 60 (Left of 40, since 20's left and right are full)

10

/ \

20 30

/ \

40 50

60

7️Insert 70 (Right of 40)

10

/ \

20 30

/ \

40 50

/ \

60 70

8️Insert 80 (Left of 50)

10

/ \

20 30

/ \

40 50

/ \ /

60 70 80

9️Insert 90 (Right of 50)

10

/ \
20 30

/ \

40 50

/ \ /\

60 70 80 90

🔟 Insert 100 (Left of 60, since left subtree is full)

10

/ \

20 30

/ \

40 50

/ \ /\

60 70 80 90

100

Summary

 Root is 10.

 Insertion follows the rule: Left first, then right, then recursively left.

 Tree grows level-wise, filling left children first.

This is how the binary tree is built step by step. Let me know if you need more details! 🚀

Introduction to Tree Traversals

"Now that we understand trees, we need ways to visit and process each node systematically. These
methods are called Tree Traversals."

Real-Life Example:

"Imagine searching for a book in a large library. There are different ways to search:"

 Row-wise: Go shelf by shelf (similar to Level Order Traversal).

 Section-wise: First check the left section, then right (similar to Preorder, Inorder, Postorder).

Ask: "Can you think of other examples where we systematically explore a structure?" (Expected
answers: File system, decision trees, family trees, etc.)
Depth-First Traversal (Preorder, Inorder, Postorder)

"Depth-First Traversal (DFS) explores one branch of a tree completely before moving to another
branch."

1️⃣ Preorder Traversal (Root → Left → Right)

1. Visit the root node.

2. Traverse the left subtree.

3. Traverse the right subtree.

Example Tree:

/\

2 3

/\ \

4 5 6

Preorder Output: 1 → 2 → 4 → 5 → 3 → 6

Python Code:

def preorder(root):

if root:

print(root.val, end=" ") # Step 1: Visit root

preorder(root.left) # Step 2: Visit left subtree

preorder(root.right) # Step 3: Visit right subtree

2️⃣ Inorder Traversal (Left → Root → Right)

1. Traverse the left subtree.

2. Visit the root node.

3. Traverse the right subtree.

Inorder Output: 4 → 2 → 5 → 1 → 3 → 6

Python Code:

def inorder(root):

if root:

inorder(root.left) # Step 1: Visit left subtree

print(root.val, end=" ") # Step 2: Visit root


inorder(root.right) # Step 3: Visit right subtree

📌 Real-Life Example: "Inorder is used in Binary Search Trees (BSTs) to get sorted data."

3️⃣ Postorder Traversal (Left → Right → Root)

1. Traverse the left subtree.

2. Traverse the right subtree.

3. Visit the root node.

Postorder Output: 4 → 5 → 2 → 6 → 3 → 1

Python Code:

def postorder(root):

if root:

postorder(root.left) # Step 1: Visit left subtree

postorder(root.right) # Step 2: Visit right subtree

print(root.val, end=" ") # Step 3: Visit root

📌 Use Case: "Postorder is used to delete trees from leaf to root."

📌 Level Order Traversal – Clear Explanation Without deque

📝 What is Level Order Traversal?

In Level Order Traversal, we visit nodes level by level from top to bottom, moving from left to right
at each level.

🌳 Example Tree

Let’s take this Binary Tree as an example:

/\

2 3

/\ \

4 5 6

Level Order Traversal Output:


👉1→2→3→4→5→6

How Does It Work?


 Start from the root (1) and print it.

 Move to the next level (2, 3) and print them.

 Move to the next level (4, 5, 6) and print them.

🚀 Step-by-Step Traversal Process

1. Start with the root node (1).

2. Print it and move to the next level (2 and 3).

3. Print 2 and 3 and move to their children (4, 5, 6).

4. Print 4, 5, 6 (no more children left).

5. Traversal is complete! 🎉

Python Code (Without deque)

class TreeNode:

def __init__(self, val):

self.val = val

self.left = None

self.right = None

def level_order(root):

if not root:

return

queue = [root] # Step 1: Use a simple list as a queue

while queue:

node = queue.pop(0) # Step 2: Remove the front node

print(node.val, end=" ") # Step 3: Print the node

if node.left: # Step 4: Add left child to queue if exists

queue.append(node.left)
if node.right: # Step 5: Add right child to queue if exists

queue.append(node.right)

level_order(root) # Output: 1 2 3 4 5 6

🔍 Step-by-Step Code Execution

🔹 Initial Queue: [1]

✅ Print 1, Add 2 & 3 to the queue.

🔹 Queue: [2, 3]

✅ Print 2, Add 4 & 5 to the queue.

🔹 Queue: [3, 4, 5]

✅ Print 3, Add 6 to the queue.

🔹 Queue: [4, 5, 6]

✅ Print 4 (No children).


✅ Print 5 (No children).
✅ Print 6 (No children).

🚀 Traversal Complete!

📌 Real-Life Example:

Customer Support System 📞

 Customers are served in a first-come, first-served manner.

 The first person in the queue gets served first, just like level order traversal.

✅ Interactive Activity:

 Ask students to stand in a queue.

 Call them one by one, mimicking level order traversal.

 This makes the concept easy to visualize and understand!

🔥 Is this clear now? Would you like me to add more examples? 🚀

What is the Height of a Binary Tree?

 Height of a node = Longest path from that node to a leaf.

 Height of the tree = Height of the root node.


📌 Formula:

Height of a Tree = Max(Height of Left Subtree, Height of Right Subtree) + 1

def height(root):

if not root:

return 0

return max(height(root.left), height(root.right)) + 1

What is the Diameter of a Binary Tree?

📌 Definition:
The diameter of a binary tree is the longest path between any two nodes in the tree.
This path may or may not pass through the root.

📌 Formula:

Diameter = Max(Diameter of Left Subtree, Diameter of Right Subtree, Longest Path through Root)

def diameter_of_binary_tree(root): # We'll use a list to store the maximum diameter found
max_diameter = [0]

def height(node):

if not node:

return 0

left_height = height(node.left)

right_height = height(node.right)

# Update the maximum diameter found so far

max_diameter[0] = max(max_diameter[0], left_height + right_height)

# Return the height of the current node

return 1 + max(left_height, right_height)

height(root) # This calculates height and updates max_diameter

return max_diameter[0]

How It Works (Step-by-Step)

1. Height Calculation:

o For each node, calculate the heights of its left and right subtrees.

o Example:

Copy

/\
2 3

/\

4 5

 At node 2: left_height = 1 (from 4), right_height = 1 (from 5)

2. Diameter Update:

o Diameter at a node = left_height + right_height.

o For node 2: 1 (left) + 1 (right) = 2 (path: 4 → 2 → 5)

3. Global Maximum:

o We keep track of the maximum diameter found (max_diameter[0]).

4. Final Result:

o The longest path in the tree is 3 (path: 4 → 2 → 1 → 3 or 5 → 2 → 1 → 3).

Key Features

✅ Easy to Understand: Uses simple height calculation.


✅ Efficient: Visits each node only once (O(n) time).
✅ No Advanced Libraries: Uses basic recursion.

Example Walkthrough

For this tree:

Copy

/\

2 3

/\

4 5

1. At Node 4 (Leaf):

o Height = 1 (base case)

2. At Node 5 (Leaf):

o Height = 1

3. At Node 2:

o Left height = 1 (from 4), Right height = 1 (from 5)

o Diameter = 1 + 1 = 2 (path: 4 → 2 → 5)
4. At Node 3 (Leaf):

o Height = 1

5. At Root (1):

o Left height = 2 (from 2), Right height = 1 (from 3)

o Diameter = 2 + 1 = 3 (path: 4 → 2 → 1 → 3)

Final Output: 3 (the longest path in the tree).

Why This Works

 The diameter is always the sum of the heights of the left and right subtrees of some node.

 By calculating heights recursively, we efficiently track the maximum diameter.

Here's a **clear, interactive 1-hour lesson plan** to teach counting leaf nodes and checking identical
trees, with simple code examples and hands-on activities:

1. Count leaf nodes in a binary tree.

2. Check if two binary trees are identical.

---

## **Part 1: Counting Leaf Nodes (30 mins)**

### **Concept: What is a Leaf Node?**

**Interactive Demo**:

- Draw this tree on the board:

```

10

/ \

5 20

/\

3 7

```

- Ask: *"Which nodes have no children?"* (Students point to 3, 7, 20)


- **Definition**: A leaf is a node with no left/right children.

### **Algorithm**

1. Traverse the tree (any order works).

2. If a node has no left/right children → increment count.

### **Simple Python Code**

def count_leaves(root):

if not root:

return 0

if not root.left and not root.right: # Leaf condition

return 1

return count_leaves(root.left) + count_leaves(root.right)

**Live Walkthrough**:

- For the example tree:

- Leaves at 3, 7, 20 → Total = 3.

**Student Activity**:

1. Draw this tree and count leaves manually:

```

/\

B C

/\

D E

```

**Answer**: 3 leaves (B, D, E).

## **Part 2: Checking Identical Trees (30 mins)**


### **Concept: When Are Trees Identical?**

**Interactive Demo**:

- Show two trees:

**Tree 1**:

```

1 Tree 2: 1

/\ /\

2 3 2 3

```

- Ask: *"Are these identical?"* (Yes!)

- Change Tree 2 to `[1,3,2]` → *"Now?"* (No, left/right swapped).

### **Algorithm**

1. Both roots must match.

2. Left subtrees must be identical.

3. Right subtrees must be identical.

### **Simple Python Code**

```python

def are_identical(root1, root2):

if not root1 and not root2: # Both empty

return True

if not root1 or not root2: # One empty

return False

return (root1.val == root2.val and

are_identical(root1.left, root2.left) and

are_identical(root1.right, root2.right))

```

**Live Walkthrough**:

- Compare `[1,2,3]` and `[1,2,3]` → `True`.


- Compare `[1,2,3]` and `[1,3,2]` → `False`.

**Student Challenge**:

- Are these identical?

**Tree A**:

```

10 Tree B: 10

/ \ / \

5 20 5 20

```

**Answer**: Yes!

---

## **Wrap-Up (5 mins)**

**Key Takeaways**:

✅ **Leaf Nodes**: Nodes with no children → count using recursion.

✅ **Identical Trees**: Roots and all subtrees must match exactly.

**Exit Ticket**:

1. How many leaves in this tree?

```

/\

6 10

/ /\

5 9 11

```

**Answer**: 3 (5, 9, 11).

2. Are these identical?


```

1 1

/\ /\

2 3 2 3

/ \

4 4

```

**Answer**: No (left child of 2 differs).

---

### **Teacher Notes**:

- **Common Pitfalls**:

- Forgetting the `not root1 and not root2` base case.

- Miscounting leaves by ignoring null checks.

- **Extension**: For advanced students, introduce iterative solutions.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy