Understanding Binary Trees | Tree Data Structure | Exploring Terminologies, Traversals, and Binary Search Trees | LeetCode Q | Resources
Ahmad Raza
Undergrad SoftwareEngineer | CGPA 3.83/4.00 | Global Nominee @NASA?? | 15X Inte'l Hackathons & Hackathon Finalist | LeetCode 350+ | 1X Hackathon Mentor | IELTS & AI Instructor | MERN Stack & Gen AI developer | C++ Python
Introduction
What are trees? So, from the first click in our mind, after we listen the word 'trees' would be the picture which I have added on top. Trees in DSA also looks the same. So, previously we discussed about linear data structures (Linear data structurs are those, where we have stored elements in linear/single level or we can say that Data Structures where we store elements in sequential order, like one after the other and an element is connected to its next as well as previous elements, like Stack, LinkedLists, Priority Queues, Queue. All these are linear/sequential order. All these structures have single level. )
But trees on the other side are non-linear data structures, also we can say that trees are called as hierarchical data structures. What this means ? Let's discuss it with an example from our Government System. Pakistan's Government System has a prime minister ( the actual leader, who has power). Then, a prime minister declare his 32-33 ministers for different Ministries like for WAPDA, FBR, IT etc. Then, each minister has his/her Secretaries like Joint, Federal, Deputy Secretary. So, this is called as hierarchy, where things are ranked according to relative status or authority and there's some levels.
Another example, we can take of Family hierarchy, where let's suppose we have a person Ahmad, ahmad has three sons and two daughters. One of his sons name is Furqan, now Furqan is married and he has four daughters. One of his daughter has three sons.
So, this would make a hierarchy, where on the top we would have grand grand parents, then grand parents, then parents, then childs, then grand childs. And here you can see humans are ranked as relative status and authority. Like after parents, childs should come, not the grand childs.
I think you now perfectly understood what's the tree actually is. See the below pinned picture.
Tree data structure is a hierarchical structure that is used to represent and organize data in a way that is easy to navigate and search. It is a collection of nodes that are connected by edges and has a hierarchical relationship between the nodes.
Terminologies
While working on trees, we would be dealing with different terminologies. W'll discuss the most using words here.
Two more important concepts :
Types of Trees in DSA
There are many types of trees, we will be discussing some of them :
Tree order Traversal
Traversing is the technique to visit all the nodes of the tree only once. Unlike the linear data structures where there's the only one logical way to traverse, trees can be traversed in different ways. We'll discuss all of them breifly here.Traversal is the most important thing in non-linear data structures. In most tree problems, traversal is the only thing needs to have understanding.
In Binary trees, we have two types of traversals:
W'll discuss both types of traversals in next section.
Depth First Search -DFS
DFS is the technique, where we start traversing from the root and ends at the most right child. In this type of traversing, we traverse node by node. Like first parent then it's left then right, not all nodes in one step.
DFS has three traversal techniques :
领英推荐
Breadth First Search -BFS
BFS is a level order traversal. Where we traverse all the nodes level by level not node by node. Like in the above picture of tree, we can see four levels for tree. So, in first turn we will visit root node. In second turn, two nodes will be visited because both are on same level. In 3rd turn, all the nodes on third level would be visited and so on.
For the BFS-Traversal we use queue ( deque ).
Some Properties of Binary Trees
LeetCode Question as an Example
Statement : You are given the root of a binary search tree and an array queries of size n consisting of positive integers.
Find a 2D array answer of size n where answer[i] = [mini, maxi]:
Return the array answer.
Coding Solution in Python
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def closestNodes(self, root: Optional[TreeNode], queries: List[int]) -> List[List[int]]:
def DFS(node, data):
if not node:
return None
DFS(node.left, data)
data.append(node.val)
DFS(node.right, data)
data = []
DFS(root, data)
n = len(data)
def calc(val):
index = bisect.bisect_left(data, val)
if index == n:
return data[-1], -1
if data[index] == val:
return [val, val]
if index == 0:
return [-1, data[0]]
return [data[index-1], data[index]]
return [calc(val) for val in queries]
Explanation of Solution
Consider the above example, where the querues list is [2, 5, 16]. So, first of all in the above code, we can see that we have defined a node class. This class is commented by LeetCode, which says us not to change the code of node class, becuase our code will be judged based on thier provided Node class, not ours.
In the Node Class, we have the current Node's value, it's left child's address and also it's right child's address.
In the Solution Class, when the excecution of our defined function starts, the line which will first excecute would be the line number : 18 where we are defining our list, because before this we only defined our function.
On line number 19, we called our function DFS(), and if we look on our function, we can clearly see that the function is an InOrder Traversal, and here instead of just printing we are storing the nodes as we traverse throughout the tree. Also, we kow that the Inorder traversal of BST(Binary Search Tree) give us sorted list. So, the array:data[] would have the sorted node's values in sorted way.
So, after the excution of line number of 19, and our function DFS() completely terminated then array : data = [ 1, 2, 4, 6, 9, 13, 14, 15 ].
Now, we again defined a function named calc(), let's see what er are calculating and how. So, in the first line of function, we are using bisect.bisect_left(x, y) function. biect.bisect_left() function always apply on sorted list x, and returns the index like where we can insert 'y' in 'x'. So that the list 'x' remains sorted as it was before. As it's bisect_left function, so it preferred first to insert element at the left side, if inserting on left side makes array unsorted then it inserted it on right side. Let's take an exampe, suppose we have array named L[1, 4, 6], and we want to insrt '3' in L with the condition that 'L' remains sorted, so we call function bisect.bisect_left ( L, 3 ). Here, our function will return index = 1, because the list would remain sorted if '3' will be on index 1. Also, we can have a poin here, that it was sure that '3' would always be on the left of '4' in sorted array, then why we are using here specifically biesct.bisect_left function ? Let's understand this by letting another case, suppose we want to insert '4' in L[ 1, 4, 6]. Now, if we call bisect.bisect_left( L, 4 ) then this function will return again '1', because it will see that if '4' inserts on index no. 2 or on index number 1 our list will remin sorted in both cases, but as in this case, it was bisect_left function that's why it will return use left index to insert, that would be '1'. But function bisect_right() will return '2' index in this case.
So, in the last line we are running a for loop where we are passing queries[ 2, 5, 15 ] elements one by one to calc function. When we pass queries[0] (2) element to calc(), bisect_left () will give us index no. '1', as in data = [ 1, 2, 4, 6, 9, 13, 14, 15 ], '2' can be inserted on index 1. Now check the if conditions, we can see that the second if condition meets with this scenerio where data[1] = queires[0] ( val which we passed, and '1' is the returned index from bisect function), So we will return a list [ 2, 2 ].
The same will happen for other tqo queries, and as the for loop ends, this would directly return as an answer.
Resources
#BinaryTree #TreeDataStructure #DataStructures #Algorithms #BinaryTreeTraversal #BinarySearchTree #TreeNodes #Coding #Programming #TechEducation #ComputerScience #TreeTraversal #DFS #BFS #LearnCoding #BinaryTreeBasics #TreesInPython #DataStructureAndAlgorithm #CodeLearning #ProgrammingTips
美国亚利桑那州立大学 Python Coding Python programming MATLAB & PYTHON DSA iCodeGuru University of Engineering and Technology, Lahore
Future AI Engineer | Sharing My Journey Toward Innovation | Passionate About Leveraging Technology to Create Impact
4 个月Very informative