linear search – binary search – hashing – hash functions – collision handling – load factors, rehashing, and efficiency,Tree ADT – Binary Tree ADT – tree traversals – binary search trees – AVL trees .
These Topics were Covered in this Material.
Make use of it.
Definition,algorithm,example with pictorial representation ,example program & Analysis of Time and space complexity for individual topics are there for your view.
SRGE Workshop on Intelligent system and Application, 27 Dec. 2017 in the framework of the int. conf of computer science, information systems, and operation research, ISSR, Cairo University
SRGE Workshop on Intelligent system and Application, 27 Dec. 2017 in the framework of the int. conf of computer science, information systems, and operation research, ISSR, Cairo University
Human Activity Recognition using Smartphone's sensor Pankaj Mishra
Human activity recognition plays significant role in medical field and in security system. In this project we have design a model which recognize a person’s activity based on Smartphone.
A 3- dimensional Smartphone sensor named accelerometer and gyroscope is used to collect time series signal, from which 26 features are generated in time and frequency domain. The activities are classified using 2 different dormant learning method i.e. k-nearest neighbor algorithm, decision tree algorithm.
Abstract:
Brain fingerprinting is based on finding that the brain generates a unique brain wave pattern when a person encounters a familiar stimulus Use of functional magnetic resonance imaging in lie detection derives from studies suggesting that persons asked to lie show different patterns of brain activity than they do when being truthful. Issues related to the use of such evidence in courts are discussed. The author concludes that neither approach is currently supported by enough data regarding its accuracy in detecting deception to warrant use in court.
In the field of criminology, a new lie detector has been developed in the United States of America. This is called “brain fingerprinting”. This invention is supposed to be the best lie detector available as on date and is said to detect even smooth criminals who pass the polygraph test (the conventional lie detector test) with ease. The new method employs brain waves, which are useful in detecting whether the person subjected to the test, remembers finer details of the crime. Even if the person willingly suppresses the necessary information, the brain wave is sure to trap him, according to the experts, who are very excited about the new kid on the block.
Introduction:
Brain Fingerprinting is a controversial proposed investigative technique that measures recognition of familiar stimuli by measuring electrical brain wave responses to words, phrases, or pictures that are presented on a computer screen. Brain fingerprinting was invented by Lawrence Farwell. The theory is that the suspect's reaction to the details of an event or activity will reflect if the suspect had prior knowledge of the event or activity. This test uses what Farwell calls the MERMER ("Memory and Encoding Related Multifaceted Electroencephalographic Response") response to detect familiarity reaction. One of the applications is lie detection. Dr. Lawrence A. Farwell has invented, developed, proven, and patented the technique of Farwell Brain Fingerprinting, a new computer-based technology to identify the perpetrator of a crime accurately and scientifically by measuring brain-wave responses to crime-relevant words or pictures presented on a computer screen. Farwell Brain Fingerprinting has proven 100% accurate in over 120 tests, including tests on FBI agents, tests for a US intelligence agency and for the US Navy, and tests on real-life situations including actual crimes..
Human Activity Recognition using Smartphone's sensor Pankaj Mishra
Human activity recognition plays significant role in medical field and in security system. In this project we have design a model which recognize a person’s activity based on Smartphone.
A 3- dimensional Smartphone sensor named accelerometer and gyroscope is used to collect time series signal, from which 26 features are generated in time and frequency domain. The activities are classified using 2 different dormant learning method i.e. k-nearest neighbor algorithm, decision tree algorithm.
Abstract:
Brain fingerprinting is based on finding that the brain generates a unique brain wave pattern when a person encounters a familiar stimulus Use of functional magnetic resonance imaging in lie detection derives from studies suggesting that persons asked to lie show different patterns of brain activity than they do when being truthful. Issues related to the use of such evidence in courts are discussed. The author concludes that neither approach is currently supported by enough data regarding its accuracy in detecting deception to warrant use in court.
In the field of criminology, a new lie detector has been developed in the United States of America. This is called “brain fingerprinting”. This invention is supposed to be the best lie detector available as on date and is said to detect even smooth criminals who pass the polygraph test (the conventional lie detector test) with ease. The new method employs brain waves, which are useful in detecting whether the person subjected to the test, remembers finer details of the crime. Even if the person willingly suppresses the necessary information, the brain wave is sure to trap him, according to the experts, who are very excited about the new kid on the block.
Introduction:
Brain Fingerprinting is a controversial proposed investigative technique that measures recognition of familiar stimuli by measuring electrical brain wave responses to words, phrases, or pictures that are presented on a computer screen. Brain fingerprinting was invented by Lawrence Farwell. The theory is that the suspect's reaction to the details of an event or activity will reflect if the suspect had prior knowledge of the event or activity. This test uses what Farwell calls the MERMER ("Memory and Encoding Related Multifaceted Electroencephalographic Response") response to detect familiarity reaction. One of the applications is lie detection. Dr. Lawrence A. Farwell has invented, developed, proven, and patented the technique of Farwell Brain Fingerprinting, a new computer-based technology to identify the perpetrator of a crime accurately and scientifically by measuring brain-wave responses to crime-relevant words or pictures presented on a computer screen. Farwell Brain Fingerprinting has proven 100% accurate in over 120 tests, including tests on FBI agents, tests for a US intelligence agency and for the US Navy, and tests on real-life situations including actual crimes..
Array is a container which can hold a fix number of items and these items should be of the same type. Most of the data structures make use of arrays to implement their algorithms. Following are the important terms to understand the concept of array.
In the binary search, if the array being searched has 32 elements in.pdfarpitaeron555
In the binary search, if the array being searched has 32 elements in it, how many elements of the
array must be examined to be certain that the array does not contain the key? What about 1024
elements? Note: the answer is the same regardless of whether the algorithm is recursive or
iterative.
Solution
Binary Search Algorithm- Fundamentals, Implementation and Analysis
Hitesh Garg | May 15, 2015 | algorithms | 5 Comments
Binary Search Algorithm and its Implementation
In our previous tutorial we discussed about Linear search algorithm which is the most basic
algorithm of searching which has some disadvantages in terms of time complexity,so to
overcome them to a level an algorithm based on dichotomic (i.e. selection between two distinct
alternatives) divide and conquer technique is used i.e. Binarysearch algorithm and it is used to
find an element in a sorted array (yes, it is a prerequisite for this algorithm and a limitation too).
In this algorithm we use the sorted array so as to reduce the time complexity to O(log n). In this,
size of the elements reduce to half after each iteration and this is achieved by comparing the
middle element with the key and if they are unequal then we choose the first or second half,
whichever is expected to hold the key (if available) based on the comparison i.e. if array is sorted
in an increasing manner and the key is smaller than middle element than definitely if key exists,
it will be in the first half, we chose it and repeat same operation again and again until key is
found or no more elements are left in the array.
Recursive Pseudocode:
1
2
3
4
5
6
7
8
9
10
11
12
// initially called with low = 0, high = N – 1
BinarySearch_Right(A[0..N-1], value, low, high) {
// invariants: value >= A[i] for all i < low
value < A[i] for all i > high
if (high < low)
return low
mid = low +((high – low) / 2) // THIS IS AN IMPORTANT STEP TO AVOID BUGS
if (A[mid] > value)
return BinarySearch_Right(A, value, low, mid-1)
else
return BinarySearch_Right(A, value, mid+1, high)
}
Iterative Pseudocode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
BinarySearch_Right(A[0..N-1], value) {
low = 0
high = N - 1
while (low <= high) {
// invariants: value >= A[i] for all i < low
value < A[i] for all i > high
mid = low +((high – low) / 2) // THIS IS AN IMPORTANT STEP TO AVOID BUGS
if (A[mid] > value)
high = mid - 1
else
low = mid + 1
}
return low
}
Asymptotic Analysis
Since this algorithm halves the no of elements to be checked after every iteration it will take
logarithmic time to find any element i.e. O(log n) (where n is number of elements in the list) and
its expected cost is also proportional to log n provided that searching and comparing cost of all
the elements is same
Data structure used -> Array
Worst case performance -> O(log n)
Best case performance -> O(1)
Average case performance -> O(log n)
Worst case space complexity -> O(1)
So the idea is-
RECURSIVE Implementation of Binary search in C programming language
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
Final project report on grocery store management system..pdfKamal Acharya
In today’s fast-changing business environment, it’s extremely important to be able to respond to client needs in the most effective and timely manner. If your customers wish to see your business online and have instant access to your products or services.
Online Grocery Store is an e-commerce website, which retails various grocery products. This project allows viewing various products available enables registered users to purchase desired products instantly using Paytm, UPI payment processor (Instant Pay) and also can place order by using Cash on Delivery (Pay Later) option. This project provides an easy access to Administrators and Managers to view orders placed using Pay Later and Instant Pay options.
In order to develop an e-commerce website, a number of Technologies must be studied and understood. These include multi-tiered architecture, server and client-side scripting techniques, implementation technologies, programming language (such as PHP, HTML, CSS, JavaScript) and MySQL relational databases. This is a project with the objective to develop a basic website where a consumer is provided with a shopping cart website and also to know about the technologies used to develop such a website.
This document will discuss each of the underlying technologies to create and implement an e- commerce website.
Saudi Arabia stands as a titan in the global energy landscape, renowned for its abundant oil and gas resources. It's the largest exporter of petroleum and holds some of the world's most significant reserves. Let's delve into the top 10 oil and gas projects shaping Saudi Arabia's energy future in 2024.
Democratizing Fuzzing at Scale by Abhishek Aryaabh.arya
Presented at NUS: Fuzzing and Software Security Summer School 2024
This keynote talks about the democratization of fuzzing at scale, highlighting the collaboration between open source communities, academia, and industry to advance the field of fuzzing. It delves into the history of fuzzing, the development of scalable fuzzing platforms, and the empowerment of community-driven research. The talk will further discuss recent advancements leveraging AI/ML and offer insights into the future evolution of the fuzzing landscape.
Quality defects in TMT Bars, Possible causes and Potential Solutions.PrashantGoswami42
Maintaining high-quality standards in the production of TMT bars is crucial for ensuring structural integrity in construction. Addressing common defects through careful monitoring, standardized processes, and advanced technology can significantly improve the quality of TMT bars. Continuous training and adherence to quality control measures will also play a pivotal role in minimizing these defects.
Industrial Training at Shahjalal Fertilizer Company Limited (SFCL)MdTanvirMahtab2
This presentation is about the working procedure of Shahjalal Fertilizer Company Limited (SFCL). A Govt. owned Company of Bangladesh Chemical Industries Corporation under Ministry of Industries.
Welcome to WIPAC Monthly the magazine brought to you by the LinkedIn Group Water Industry Process Automation & Control.
In this month's edition, along with this month's industry news to celebrate the 13 years since the group was created we have articles including
A case study of the used of Advanced Process Control at the Wastewater Treatment works at Lleida in Spain
A look back on an article on smart wastewater networks in order to see how the industry has measured up in the interim around the adoption of Digital Transformation in the Water Industry.
Student information management system project report ii.pdfKamal Acharya
Our project explains about the student management. This project mainly explains the various actions related to student details. This project shows some ease in adding, editing and deleting the student details. It also provides a less time consuming process for viewing, adding, editing and deleting the marks of the students.
Courier management system project report.pdfKamal Acharya
It is now-a-days very important for the people to send or receive articles like imported furniture, electronic items, gifts, business goods and the like. People depend vastly on different transport systems which mostly use the manual way of receiving and delivering the articles. There is no way to track the articles till they are received and there is no way to let the customer know what happened in transit, once he booked some articles. In such a situation, we need a system which completely computerizes the cargo activities including time to time tracking of the articles sent. This need is fulfilled by Courier Management System software which is online software for the cargo management people that enables them to receive the goods from a source and send them to a required destination and track their status from time to time.
Forklift Classes Overview by Intella PartsIntella Parts
Discover the different forklift classes and their specific applications. Learn how to choose the right forklift for your needs to ensure safety, efficiency, and compliance in your operations.
For more technical information, visit our website https://intellaparts.com
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdffxintegritypublishin
Advancements in technology unveil a myriad of electrical and electronic breakthroughs geared towards efficiently harnessing limited resources to meet human energy demands. The optimization of hybrid solar PV panels and pumped hydro energy supply systems plays a pivotal role in utilizing natural resources effectively. This initiative not only benefits humanity but also fosters environmental sustainability. The study investigated the design optimization of these hybrid systems, focusing on understanding solar radiation patterns, identifying geographical influences on solar radiation, formulating a mathematical model for system optimization, and determining the optimal configuration of PV panels and pumped hydro storage. Through a comparative analysis approach and eight weeks of data collection, the study addressed key research questions related to solar radiation patterns and optimal system design. The findings highlighted regions with heightened solar radiation levels, showcasing substantial potential for power generation and emphasizing the system's efficiency. Optimizing system design significantly boosted power generation, promoted renewable energy utilization, and enhanced energy storage capacity. The study underscored the benefits of optimizing hybrid solar PV panels and pumped hydro energy supply systems for sustainable energy usage. Optimizing the design of solar PV panels and pumped hydro energy supply systems as examined across diverse climatic conditions in a developing country, not only enhances power generation but also improves the integration of renewable energy sources and boosts energy storage capacities, particularly beneficial for less economically prosperous regions. Additionally, the study provides valuable insights for advancing energy research in economically viable areas. Recommendations included conducting site-specific assessments, utilizing advanced modeling tools, implementing regular maintenance protocols, and enhancing communication among system components.
Event Management System Vb Net Project Report.pdfKamal Acharya
In present era, the scopes of information technology growing with a very fast .We do not see any are untouched from this industry. The scope of information technology has become wider includes: Business and industry. Household Business, Communication, Education, Entertainment, Science, Medicine, Engineering, Distance Learning, Weather Forecasting. Carrier Searching and so on.
My project named “Event Management System” is software that store and maintained all events coordinated in college. It also helpful to print related reports. My project will help to record the events coordinated by faculties with their Name, Event subject, date & details in an efficient & effective ways.
In my system we have to make a system by which a user can record all events coordinated by a particular faculty. In our proposed system some more featured are added which differs it from the existing system such as security.
1. MS.K.Amuthachenthiru-RIT/AD
Department of Artificial Intelligence and Data Science
Academic Year: 2022- 2023 (Even Semester)
SUB.CODE/NAME:AD3251/DATA STRUCTURES DESIGN
LINEAR SEARCH:
DEFINITION:
A method of locating elements in a list is linear search. A sequential search is another
name for it. Because it searches for the requested element in a sequential way. It evaluates
each and every element in relation to the value we're looking for. The element is discovered if
both match and the procedure returns the key's index position.
KEYPOINTS TO REMEMBER:
1. Begin your search with the first element and check the key with each element in the
list.
2. If an element is discovered, the key's index position is returned.
3. If the element isn't discovered, the return value isn't present.
ALGORITHM:
1. Create a function linear_search()
2. Declare three parameters array, length of the array, and number to be found.
3. Initialize for loop
4. Iterate each element and compare the key value.
5. If the element is present return index
6. Else return not present
PROGRAM:
def linear_search(arr, a, b):
# Going through array
for i in range(0, a):
if (arr[i] == b):
return i
return -1
arr = [9, 7, 5, 3, 1]
print("The array given is ", arr)
2. MS.K.Amuthachenthiru-RIT/AD
b = 5
print("Element to be found is ", b)
a = len(arr)
index = linear_search(arr, a, b)
if(index == -1):
print("Element is not in the list")
else:
print("Index of the element is: ", index)
output:
The array given is [9, 7, 5, 3, 1]
Element to be found is 5
Index of the element is: 2
DIAGRAM EXPLANATION:
Step 1:
3. MS.K.Amuthachenthiru-RIT/AD
Step 2:
Step 3:
ANALYSIS:
Time Complexity:O(n)
Space Complexity:O(1)
BINARY SEARCH:
DEFINITION:
Binary search algorithms are also known as half interval search. They return the position of a
target value in a sorted list.
These algorithms use the “divide and conquer” technique to find the value's position.
4. MS.K.Amuthachenthiru-RIT/AD
ALGORITHM:
binarySearch(arr, x, low, high)
if low > high
return False
else
mid = (low + high) / 2
if x == arr[mid]
return mid
else if x > arr[mid] // x is on the right side
return binarySearch(arr, x, mid + 1, high)
else // x is on the left side
return binarySearch(arr, x, low, mid - 1)
Program:
5. MS.K.Amuthachenthiru-RIT/AD
# Binary Search in python
def binarySearch(array, x, low, high):
if high >= low:
mid = low + (high - low)//2
# If found at mid, then return it
if array[mid] == x:
return mid
# Search the left half
elif array[mid] > x:
return binarySearch(array, x, low, mid-1)
# Search the right half
else:
return binarySearch(array, x, mid + 1, high)
else:
return -1
array = [3, 4, 5, 6, 7, 8, 9]
x = 4
result = binarySearch(array, x, 0, len(array)-1)
if result != -1:
print("Element is present at index " + str(result))
else:
print("Not found")
ANALYSIS:
Time Complexities
6. MS.K.Amuthachenthiru-RIT/AD
Best case complexity: O(1)
Average case complexity: O(log n)
Worst case complexity: O(log n)
Space Complexity
The space complexity of the binary search is O(1).
HASHING:
DEFINITION:
A hash is a value that has a fixed length, and it is generated using a mathematical
formula. Hash values are used in data compression, cryptology, etc. In data indexing, hash
values are used because they have fixed length size regardless of the values that were used to
generate them. It makes hash values to occupy minimal space compared to other values of
varying lengths.
HASH TABLE:
7. MS.K.Amuthachenthiru-RIT/AD
A HASH TABLE is a data structure that stores values using a pair of keys and
values. Each value is assigned a unique key that is generated using a hash function.
The name of the key is used to access its associated value. This makes searching for values in
a hash table very fast, irrespective of the number of items in the hash table.
HASH FUNCTIONS
For example, if we want to store employee records, and each employee is uniquely
identified using an employee number.We can use the employee number as the key and assign
the employee data as the value.
The above approach will require extra free space of the order of (m * n2
) where the
variable m is the size of the array, and the variable n is the number of digits for the employee
number. This approach introduces a storage space problem.
A hash function solves the above problem by getting the employee number and using it to
generate a hash integer value, fixed digits, and optimizing storage space. The purpose of a
hash function is to create a key that will be used to reference the value that we want to store.
The function accepts the value to be saved then uses an algorithm to calculate the value of the
key.
The following is an example of a simple hash function
h(k) = k1 % m
HERE,
h(k) is the hash function that accepts a parameter k. The parameter k is the value that
we want to calculate the key for.
k1 % m is the algorithm for our hash function where k1 is the value we want to store,
and m is the size of the list. We use the modulus operator to calculate the key.
Example
Let’s assume that we have a list with a fixed size of 3 and the following values
[1,2,3]
We can use the above formula to calculate the positions that each value should occupy.
The following image shows the available indexes in our hash table.
8. MS.K.Amuthachenthiru-RIT/AD
Step 1)
Calculate the position that will be occupied by the first value like so
h(1) = 1 % 3
= 1
The value 1 will occupy the space on index 1
Step 2)
Calculate the position that will be occupied by the second value
h(2) = 2 % 3
= 2
The value 2 will occupy the space on index 2
Step 3)
Calculate the position that will be occupied by the third value.
h(3) = 3 % 3
= 0
The value 3 will occupy the space on index 0
Final Result
9. MS.K.Amuthachenthiru-RIT/AD
Our filled in hash table will now be as follows.
COLLISION
A collision occurs when the algorithm generates the same hash for more than one
value.
Let’s look at an EXAMPLE.
Suppose we have the following list of values
[3,2,9,11,7]
Let’s assume that the size of the hash table is 7, and we will use the formula (k1 % m) where
m is the size of the hash table.
The following table shows the hash values that will be generated.
Key Hash Algorithm (k1 % m) Hash Value
3 3 % 7 3
2 3 % 7 2
9 3 % 7 2
11 3 % 7 4
7 3 % 7 0
10. MS.K.Amuthachenthiru-RIT/AD
As we can see from the above results, the values 2 and 9 have the same hash value, and we
cannot store more than one value at each position.
The given problem can be solved by either using chaining or probing. The following sections
discuss chaining and probing in detail.
CHAINING
Chaining is a technique that is used to solve the problem of collision by using linked lists that
each have unique indexes.
The following image visualizes how a chained list looks like
Both 2 and 9 occupy the same index, but they are stored as linked lists. Each list has a unique
identifier.
Benefits of chained lists
The following are the benefits of chained lists:
Chained lists have better performance when inserting data because the order of insert
is O(1).
It is not necessary to resize a hash table that uses a chained list.
11. MS.K.Amuthachenthiru-RIT/AD
It can easily accommodate a large number of values as long as free space is available.
Probing
The other technique that is used to resolve collision is probing. When using the probing
method, if a collision occurs, we can simply move on and find an empty slot to store our
value.
The following are the methods of probing:
Method Description
Linear
probing
Just like the name suggests, this method searches for empty slots linearly starting from
the position where the collision occurred and moving forward. If the end of the list is
reached and no empty slot is found. The probing starts at the beginning of the list.
Quadratic
probing
This method uses quadratic polynomial expressions to find the next available free slot.
Double
Hashing
This technique uses a secondary hash function algorithm to find the next free available
slot.
Using our above example, the hash table after using probing would appear as follows:
Hash table operations
12. MS.K.Amuthachenthiru-RIT/AD
Here, are the Operations supported by Hash tables:
Insertion – this Operation is used to add an element to the hash table
Searching – this Operation is used to search for elements in the hash table using the
key
Deleting – this Operation is used to delete elements from the hash table
Inserting data operation
The insert operation is used to store values in the hash table. When a new value is stored in
the hash table, it is assigned an index number. The index number is calculated using the hash
function. The hash function resolves any collisions that occur when calculating the index
number.
Search for data operation
The search operation is used to look-up values in the hash table using the index number. The
search operation returns the value that is linked to the search index number. For example, if
we store the value 6 at index 2, the search operation with index number 2 will return the
value 6.
Delete data operation
The delete operation is used to remove a value from a hash table. To delete the Operation is
done using the index number. Once a value has been deleted, the index number is made free.
It can be used to store other values using the insert operation.
Hash Table Implementation with Python Example
Let’s look at a simple example that calculates the hash value of a key
def hash_key( key, m):
return key % m
m = 7
print(f'The hash value for 3 is {hash_key(3,m)}')
print(f'The hash value for 2 is {hash_key(2,m)}')
print(f'The hash value for 9 is {hash_key(9,m)}')
print(f'The hash value for 11 is {hash_key(11,m)}')
print(f'The hash value for 7 is {hash_key(7,m)}')
Advantages of hash tables
13. MS.K.Amuthachenthiru-RIT/AD
Here, are pros/benefits of using hash tables:
Hash tables have high performance when looking up data, inserting, and deleting
existing values.
The time complexity for hash tables is constant regardless of the number of items in
the table.
They perform very well even when working with large datasets.
Disadvantages of hash tables
Here, are cons of using hash tables:
You cannot use a null value as a key.
Collisions cannot be avoided when generating keys using. hash functions. Collisions
occur when a key that is already in use is generated.
If the hashing function has many collisions, this can lead to performance decrease.
ANALYSIS:
Time Complexity:O(n)
Space Complexity:O(1)
LOAD FACTOR is defined as (m/n) where n is the total size of the hash table and m is the
preferred number of entries which can be inserted before a increment in size of the
underlying data structure is required.
How is the Load Factor Used?
The Load Factor decides “when to increase the size of the hash Table.”
The load factor can be decided using the following formula:
The initial capacity of the HashTable * Load factor of the HashTable
E.g. If The initial capacity of HashTable is = 16
And the load factor of HashTable = 0.75
According to the formula as mentioned above: 16 * 0.75 = 12
It represents that the 12th key-value pair of a HashTable will keep its size to 16.
As soon as the 13th element (key-value pair) will come into the HashTable, it will increase its
size from 16 buckets to 16 * 2 = 32 buckets.
14. MS.K.Amuthachenthiru-RIT/AD
Another way to calculate size:
When the current load factor becomes equal to the defined load factor i.e. 0.75, the hashmap
increases its capacity.
Where:
m – is the number of entries in a HashTable
n – is the total size of HashTable
What is Rehashing?
Rehashing is a technique in which the table is resized, i.e., the size of table is doubled by
creating a new table.
Why Rehashing?
Rehashing is done because whenever key-value pairs are inserted into the map, the load
factor increases, which implies that the time complexity also increases as explained above.
This might not give the required time complexity of O(1). Hence, rehash must be done,
increasing the size of the bucketArray so as to reduce the load factor and the time complexity.
Rehashing Steps –
For each addition of a new entry to the map, check the current load factor.
If it’s greater than its pre-defined value, then Rehash.
For Rehash, make a new array of double the previous size and make it the new bucket array.
Then traverse to each element in the old bucketArray and insert them back so as to insert it
into the new larger bucket array.
Consider we have to insert the elements 37, 90, 55, 22, 17, 49, and 87. the table size is
10 and will use hash function:
H(key) = key mod tablesize
37 % 10 = 7
90 % 10= 0
55 % 10 = 5
22 % 10 = 2
17 % 10 = 7
49 % 10 = 9
Now this table is almost full and if we try to insert more elements collisions will occur
and eventually further insertions will fail. Hence we will rehash by doubling the table
size. The old table size is 10 then we should double this size for new table, that
15. MS.K.Amuthachenthiru-RIT/AD
becomes 20. But 20 is not a prime number, we will prefer to make the table size as 23.
And new hash function will be
H(key) key mod 23
37 % 23 = 14
90 % 23 = 21
55 % 23 = 9
22 % 23 = 22
17 % 23 = 17
49 % 23 = 3
87 % 23 = 18
Now the hash table is sufficiently large to accommodate new insertions.
TREE ADT:
A tree is a nonlinear hierarchical data structure that consists of nodes connected by
edges.
TREE TERMINOLOGIES
Node
A node is an entity that contains a key or value and pointers to its child nodes.
The last nodes of each path are called leaf nodes or external nodes that do not contain a
link/pointer to child nodes.
The node having at least a child node is called an internal node.
Edge
It is the link between any two nodes.
16. MS.K.Amuthachenthiru-RIT/AD
Nodes and edges of a tree
Root
It is the topmost node of a tree.
Height of a Node
The height of a node is the number of edges from the node to the deepest leaf (ie. the longest
path from the node to a leaf node).
Depth of a Node
The depth of a node is the number of edges from the root to the node.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the deepest node.
Height and depth of each node in a tree
17. MS.K.Amuthachenthiru-RIT/AD
Degree of a Node
The degree of a node is the total number of branches of that node.
Forest
A collection of disjoint trees is called a forest.
Creating forest from a tree
You can create a forest by cutting the root of a tree.
TREE TRAVERSAL
Traversing a tree means visiting every node in the tree.
Now we traverse to the subtree pointed on the TOP of the stack.
Again, we follow the same rule of inorder
Left subtree -> root -> right subtree
After traversing the left subtree, we are left with
situation of stack after traversing left subtree, stack now contains the elements of left subtree,
followed by root, followed by right child of root
Since the node "5" doesn't have any subtrees, we print it directly. After that we print its
parent "12" and then the right child "6".
Putting everything on a stack was helpful because now that the left-subtree of the root node
has been traversed, we can print it and go to the right subtree.
18. MS.K.Amuthachenthiru-RIT/AD
After going through all the elements, we get the inorder traversal as
5 -> 12 -> 6 -> 1 -> 9
We don't have to create the stack ourselves because recursion maintains the correct order for
us.
PROGRAM:
# Tree traversal in Python
class Node:
def __init__(self, item):
self.left = None
self.right = None
self.val = item
def inorder(root):
if root:
# Traverse left
inorder(root.left)
# Traverse root
print(str(root.val) + "->", end='')
# Traverse right
inorder(root.right)
def postorder(root):
if root:
# Traverse left
postorder(root.left)
20. MS.K.Amuthachenthiru-RIT/AD
preorder(root)
print("nPostorder traversal ")
postorder(root)
BINARY TREE
A binary tree is a tree data structure in which each parent node can have at most two
children. Each node of a binary tree consists of three items:
data item
address of left child
address of right child
Types of Binary Tree
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.
21. MS.K.Amuthachenthiru-RIT/AD
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. Degenerate or Pathological Tree
A degenerate or pathological tree is the tree having a single child either left or right.
22. MS.K.Amuthachenthiru-RIT/AD
5. Skewed Binary Tree
A skewed binary tree is a pathological/degenerate tree in which the tree is either dominated
by the left nodes or the right nodes. Thus, there are two types of skewed binary tree: left-
skewed binary tree and right-skewed binary tree.
6. 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 Tree Representation
23. MS.K.Amuthachenthiru-RIT/AD
A node of a binary tree is represented by a structure containing a data part and two
pointers to other structures of the same type.
PROGRAM:
# Binary Tree in Python
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
# Traverse preorder
def traversePreOrder(self):
print(self.val, end=' ')
if self.left:
self.left.traversePreOrder()
if self.right:
self.right.traversePreOrder()
# Traverse inorder
24. MS.K.Amuthachenthiru-RIT/AD
def traverseInOrder(self):
if self.left:
self.left.traverseInOrder()
print(self.val, end=' ')
if self.right:
self.right.traverseInOrder()
# Traverse postorder
def traversePostOrder(self):
if self.left:
self.left.traversePostOrder()
if self.right:
self.right.traversePostOrder()
print(self.val, end=' ')
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
print("Pre order Traversal: ", end="")
root.traversePreOrder()
print("nIn order Traversal: ", end="")
root.traverseInOrder()
25. MS.K.Amuthachenthiru-RIT/AD
print("nPost order Traversal: ", end="")
root.traversePostOrder()
ANALYSIS:
Time Complexity of different operations in Binary Tree:
OPERATION WORST CASE AVERAGE CASE BEST CASE
Insert O(N) O(N0.5
) O(logN)
Search O(N) O(N0.5
) O(1)
Delete O(N) O(N0.5
) O(logN)
Space Complexity of different operations in Binary Tree:
OPERATION ITERATIVE RECURSIVE, AVERAGE
Insert O(1) O(H) = O(N0.5
)
Search O(1) O(H) = O(N0.5
)
Delete O(1) O(H) = O(N0.5
)
where N = number of nodes in Binary Tree, H = height of Binary Tree
BINARY SEARCH TREE:
Binary search tree is a data structure that quickly allows us to maintain a sorted list of
numbers.
It is called a binary tree because each tree node has a maximum of two children.
It is called a search tree because it can be used to search for the presence of a number
in O(log(n)) time.
The properties that separate a binary search tree from a regular binary tree is
1. All nodes of left subtree are less than the root node
2. All nodes of right subtree are more than the root node
3. Both subtrees of each node are also BSTs i.e. they have the above two properties
26. MS.K.Amuthachenthiru-RIT/AD
A tree having a right subtree with one value smaller than the root is shown to
demonstrate that it is not a valid binary search tree
The binary tree on the right isn't a binary search tree because the right subtree of the node "3"
contains a value smaller than it.
There are two basic operations that you can perform on a binary search tree:
Search Operation
The algorithm depends on the property of BST that if each left subtree has values below root
and each right subtree has values above the root.
If the value is below the root, we can say for sure that the value is not in the right subtree; we
need to only search in the left subtree and if the value is above the root, we can say for sure
that the value is not in the left subtree; we need to only search in the right subtree.
Algorithm:
if root == NULL
return NULL;
If number == root->data
return root->data;
If number < root->data
return search(root->left)
If number > root->data
return search(root->right)Let us try to visualize this with a diagram.
28. MS.K.Amuthachenthiru-RIT/AD
4 is not found so, traverse through the right subtree of 3
4 is not found so, traverse through the left subtree of 6
4 is found
If the value is found, we return the value so that it gets propagated in each recursion step as
shown in the image below.
If you might have noticed, we have called return search(struct node*) four times. When we
return either the new node or NULL, the value gets returned again and again until
search(root) returns the final result.
29. MS.K.Amuthachenthiru-RIT/AD
If the value is found in any of the subtrees, it is propagated up so that in the end it is returned,
otherwise null is returned
If the value is not found, we eventually reach the left or right child of a leaf node which is
NULL and it gets propagated and returned.
Insert Operation
Inserting a value in the correct position is similar to searching because we try to maintain the
rule that the left subtree is lesser than root and the right subtree is larger than root.
We keep going to either right subtree or left subtree depending on the value and when we
reach a point left or right subtree is null, we put the new node there.
Algorithm:
If node == NULL
return createNode(data)
if (data < node->data)
node->left = insert(node->left, data);
else if (data > node->data)
node->right = insert(node->right, data);
return node;
The algorithm isn't as simple as it looks. Let's try to visualize how we add a number to an
existing BST.
31. MS.K.Amuthachenthiru-RIT/AD
4<6 so, transverse through the left child of 6
Insert 4 as a left child of 6
We have attached the node but we still have to exit from the function without doing any
damage to the rest of the tree. This is where the return node; at the end comes in handy. In
the case of NULL, the newly created node is returned and attached to the parent node,
otherwise the same node is returned without any change as we go up until we return to the
root.
This makes sure that as we move back up the tree, the other node connections aren't changed.
Deletion Operation
There are three cases for deleting a node from a binary search tree.
Case I
In the first case, the node to be deleted is the leaf node. In such a case, simply delete the node
from the tree.
32. MS.K.Amuthachenthiru-RIT/AD
4 is to be deleted
Delete the node
Case II
In the second case, the node to be deleted lies has a single child node. In such a case follow
the steps below:
1. Replace that node with its child node.
2. Remove the child node from its original position.
6 is to be deleted
33. MS.K.Amuthachenthiru-RIT/AD
copy the value of its child to the node and delete the child
Final tree
Case III
In the third case, the node to be deleted has two children. In such a case follow the steps
below:
1. Get the inorder successor of that node.
2. Replace the node with the inorder successor.
3. Remove the inorder successor from its original position.
34. MS.K.Amuthachenthiru-RIT/AD
3 is to be deleted
Copy the value of the inorder successor (4) to the node
Delete the inorder successor# Binary Search Tree operations in Python
# Create a node
class Node:
def __init__(self, key):
self.key = key
self.left = None
self.right = None
# Inorder traversal
def inorder(root):
if root is not None:
# Traverse left
inorder(root.left)
# Traverse root
35. MS.K.Amuthachenthiru-RIT/AD
print(str(root.key) + "->", end=' ')
# Traverse right
inorder(root.right)
# Insert a node
def insert(node, key):
# Return a new node if the tree is empty
if node is None:
return Node(key)
# Traverse to the right place and insert the node
if key < node.key:
node.left = insert(node.left, key)
else:
node.right = insert(node.right, key)
return node
# Find the inorder successor
def minValueNode(node):
current = node
# Find the leftmost leaf
while(current.left is not None):
current = current.left
return current
# Deleting a node
def deleteNode(root, key):
# Return if the tree is empty
if root is None:
return root
# Find the node to be deleted
36. MS.K.Amuthachenthiru-RIT/AD
if key < root.key:
root.left = deleteNode(root.left, key)
elif(key > root.key):
root.right = deleteNode(root.right, key)
else:
# If the node is with only one child or no child
if root.left is None:
temp = root.right
root = None
return temp
elif root.right is None:
temp = root.left
root = None
return temp
# If the node has two children,
# place the inorder successor in position of the node to be deleted
temp = minValueNode(root.right)
root.key = temp.key
# Delete the inorder successor
root.right = deleteNode(root.right, temp.key)
return root
root = None
root = insert(root, 8)
root = insert(root, 3)
root = insert(root, 1)
root = insert(root, 6)
root = insert(root, 7)
root = insert(root, 10)
root = insert(root, 14)
root = insert(root, 4)
print("Inorder traversal: ", end=' ')
inorder(root)
37. MS.K.Amuthachenthiru-RIT/AD
print("nDelete 10")
root = deleteNode(root, 10)
print("Inorder traversal: ", end=' ')
inorder(root)
Binary Search Tree Complexities
Time Complexity
Operation Best Case Complexity Average Case Complexity Worst Case Complexity
Search O(log n) O(log n) O(n)
Insertion O(log n) O(log n) O(n)
Deletion O(log n) O(log n) O(n)
Here, n is the number of nodes in the tree.
Space Complexity
The space complexity for all the operations is O(n).
AVL TREE:
AVL tree is a self-balancing binary search tree in which each node maintains extra
information called a balance factor whose value is either -1, 0 or +1.
AVL tree got its name after its inventor Georgy Adelson-Velsky and Landis.
Balance Factor
Balance factor of a node in an AVL tree is the difference between the height of the
left subtree and that of the right subtree of that node.
Balance Factor = (Height of Left Subtree - Height of Right Subtree) or (Height of Right
Subtree - Height of Left Subtree)
The self balancing property of an avl tree is maintained by the balance factor. The
value of balance factor should always be -1, 0 or +1.
An example of a balanced avl tree is:
38. MS.K.Amuthachenthiru-RIT/AD
Avl tree
Operations on an AVL tree
Various operations that can be performed on an AVL tree are:
Rotating the subtrees in an AVL Tree
In rotation operation, the positions of the nodes of a subtree are interchanged.
There are two types of rotations:
Left Rotate
In left-rotation, the arrangement of the nodes on the right is transformed into the
arrangements on the left node.
Algorithm
1. Let the initial tree be: Left rotate
39. MS.K.Amuthachenthiru-RIT/AD
2. If y has a left subtree, assign x as the parent of the left subtree of y.
3. Assign x as the parent of the left subtree of y
4. If the parent of x is NULL, make y as the root of the tree.
5. Else if x is the left child of p, make y as the left child of p.
6. Else assign y as the right child of p.
7. Change the parent of x to that of y
8. Make y as the parent of x.
9. Assign y as the parent of x.
Right Rotate
In left-rotation, the arrangement of the nodes on the left is transformed into the arrangements
on the right node.
40. MS.K.Amuthachenthiru-RIT/AD
1. Let the initial tree be:
2. Initial tree
3. If x has a right subtree, assign y as the parent of the right subtree of x.
4. Assign y as the parent of the right subtree of x
5. If the parent of y is NULL, make x as the root of the tree.
6. Else if y is the right child of its parent p, make x as the right child of p.
7. Else assign x as the left child of p.
8. . Assign the parent of y as the parent of x
41. MS.K.Amuthachenthiru-RIT/AD
9. Assign x as the parent of y
Left-Right and Right-Left Rotate
In left-right rotation, the arrangements are first shifted to the left and then to the right.
1. Do left rotation on x-y.
Left rotate x-y
2. Do right rotation on y-z.
42. MS.K.Amuthachenthiru-RIT/AD
3. Right rotate z-y
In right-left rotation, the arrangements are first shifted to the right and then to the left.
1. Do right rotation on x-y.
2. Right rotate x-y
3. Do left rotation on z-y.
Left rotate z-y
Algorithm to insert a newNode
A newNode is always inserted as a leaf node with balance factor equal to 0.
43. MS.K.Amuthachenthiru-RIT/AD
1. Let the initial tree be:
2. Initial tree for insertion
Let the node to be inserted be: New node
3. Go to the appropriate leaf node to insert a newNode using the following recursive steps.
Compare newKey with rootKey of the current tree.
a. If newKey < rootKey, call insertion algorithm on the left subtree of the current node until the
leaf node is reached.
b. Else if newKey > rootKey, call insertion algorithm on the right subtree of current node until
the leaf node is reached.
c. Else, return leafNode.
d. Finding the location to insert newNode
4. Compare leafKey obtained from the above steps with newKey:
44. MS.K.Amuthachenthiru-RIT/AD
a. If newKey < leafKey, make newNode as the leftChild of leafNode.
b. Else, make newNode as rightChild of leafNode.
c. Inserting the new node
5. Update balanceFactor of the nodes.
6. Updating the balance factor after insertion
7. If the nodes are unbalanced, then rebalance the node.
45. MS.K.Amuthachenthiru-RIT/AD
a. If balanceFactor > 1, it means the height of the left subtree is greater than that of the right
subtree. So, do a right rotation or left-right rotation
a. If newNodeKey < leftChildKey do right rotation.
b. Else, do left-right rotation.
c. Balancing the tree with rotation
d. Balancing the tree with rotation
b. If balanceFactor < -1, it means the height of the right subtree is greater than that of the left
subtree. So, do right rotation or right-left rotation
a. If newNodeKey > rightChildKey do left rotation.
b. Else, do right-left rotation
46. MS.K.Amuthachenthiru-RIT/AD
8. The final tree is Final balanced tree
Algorithm to Delete a node
A node is always deleted as a leaf node. After deleting a node, the balance factors of the
nodes get changed. In order to rebalance the balance factor, suitable rotations are performed.
1. Locate nodeToBeDeleted (recursion is used to find nodeToBeDeleted in the code used
below).
2. Locating the node to be deleted
47. MS.K.Amuthachenthiru-RIT/AD
3. There are three cases for deleting a node:
a. If nodeToBeDeleted is the leaf node (ie. does not have any child), then
remove nodeToBeDeleted.
b. If nodeToBeDeleted has one child, then substitute the contents of nodeToBeDeleted with
that of the child. Remove the child.
c. If nodeToBeDeleted has two children, find the inorder successor w of nodeToBeDeleted (ie.
node with a minimum value of key in the right subtree).
Finding the successor
a. Substitute the contents of nodeToBeDeleted with that of w.
b. Substitute the node to be deleted
48. MS.K.Amuthachenthiru-RIT/AD
c. Remove the leaf node w.
d. Remove w
4. Update balanceFactor of the nodes.
5. Update bf
6. Rebalance the tree if the balance factor of any of the nodes is not equal to -1, 0 or 1.
a. If balanceFactor of currentNode > 1,
a. If balanceFactor of leftChild >= 0, do right rotation.
49. MS.K.Amuthachenthiru-RIT/AD
b. Right-rotate for balancing the tree
c. Else do left-right rotation.
b. If balanceFactor of currentNode < -1,
a. If balanceFactor of rightChild <= 0, do left rotation.
b. Else do right-left rotation.
7. The final tree is: Avl tree final
Program:
# AVL tree implementation in Python
import sys
# Create a tree node
class TreeNode(object):
def __init__(self, key):
self.key = key
self.left = None
self.right = None
self.height = 1
50. MS.K.Amuthachenthiru-RIT/AD
class AVLTree(object):
# Function to insert a node
def insert_node(self, root, key):
# Find the correct location and insert the node
if not root:
return TreeNode(key)
elif key < root.key:
root.left = self.insert_node(root.left, key)
else:
root.right = self.insert_node(root.right, key)
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
# Update the balance factor and balance the tree
balanceFactor = self.getBalance(root)
if balanceFactor > 1:
if key < root.left.key:
return self.rightRotate(root)
else:
root.left = self.leftRotate(root.left)
51. MS.K.Amuthachenthiru-RIT/AD
return self.rightRotate(root)
if balanceFactor < -1:
if key > root.right.key:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
# Function to delete a node
def delete_node(self, root, key):
# Find the node to be deleted and remove it
if not root:
return root
elif key < root.key:
root.left = self.delete_node(root.left, key)
elif key > root.key:
root.right = self.delete_node(root.right, key)
else:
if root.left is None:
temp = root.right
52. MS.K.Amuthachenthiru-RIT/AD
root = None
return temp
elif root.right is None:
temp = root.left
root = None
return temp
temp = self.getMinValueNode(root.right)
root.key = temp.key
root.right = self.delete_node(root.right,
temp.key)
if root is None:
return root
# Update the balance factor of nodes
root.height = 1 + max(self.getHeight(root.left),
self.getHeight(root.right))
balanceFactor = self.getBalance(root)
# Balance the tree
if balanceFactor > 1:
if self.getBalance(root.left) >= 0:
return self.rightRotate(root)
53. MS.K.Amuthachenthiru-RIT/AD
else:
root.left = self.leftRotate(root.left)
return self.rightRotate(root)
if balanceFactor < -1:
if self.getBalance(root.right) <= 0:
return self.leftRotate(root)
else:
root.right = self.rightRotate(root.right)
return self.leftRotate(root)
return root
# Function to perform left rotation
def leftRotate(self, z):
y = z.right
T2 = y.left
y.left = z
z.right = T2
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
54. MS.K.Amuthachenthiru-RIT/AD
return y
# Function to perform right rotation
def rightRotate(self, z):
y = z.left
T3 = y.right
y.right = z
z.left = T3
z.height = 1 + max(self.getHeight(z.left),
self.getHeight(z.right))
y.height = 1 + max(self.getHeight(y.left),
self.getHeight(y.right))
return y
# Get the height of the node
def getHeight(self, root):
if not root:
return 0
return root.height
# Get balance factore of the node
def getBalance(self, root):
if not root:
55. MS.K.Amuthachenthiru-RIT/AD
return 0
return self.getHeight(root.left) - self.getHeight(root.right)
def getMinValueNode(self, root):
if root is None or root.left is None:
return root
return self.getMinValueNode(root.left)
def preOrder(self, root):
if not root:
return
print("{0} ".format(root.key), end="")
self.preOrder(root.left)
self.preOrder(root.right)
# Print the tree
def printHelper(self, currPtr, indent, last):
if currPtr != None:
sys.stdout.write(indent)
if last:
sys.stdout.write("R----")
indent += " "
else:
56. MS.K.Amuthachenthiru-RIT/AD
sys.stdout.write("L----")
indent += "| "
print(currPtr.key)
self.printHelper(currPtr.left, indent, False)
self.printHelper(currPtr.right, indent, True)
myTree = AVLTree()
root = None
nums = [33, 13, 52, 9, 21, 61, 8, 11]
for num in nums:
root = myTree.insert_node(root, num)
myTree.printHelper(root, "", True)
key = 13
root = myTree.delete_node(root, key)
print("After Deletion: ")
myTree.printHelper(root, "", True)
ANALYSIS:
Complexities of Different Operations on an AVL Tree
Insertion Deletion Search
O(log n) O(log n) O(log n)
AVL Tree Applications
For indexing large records in databases