OUTCOME 1 AND 2 Data Structure and Algorithm Notes
OUTCOME 1 AND 2 Data Structure and Algorithm Notes
One
APPLY ALGORITHM FUNDAMENTALS
1.1 Number systems are correctly converted according to the base conversion methods
Number systems are determined by the base representing valid digits used to represent a number. The four
types of number systems used in computing are decimal (base 10), binary (base 2), octal (base 8), and
hexadecimal (base 16) number systems.
Decimal number system consists of ten digits 0-9 most of us are familiar with. Because the decimal
number system has ten digits, it is also known as a base 10 or denary number system. In computing,
counting of decimal numbers start from 0.
APPLY DATA STRUCTURE AND ALGORITHM 2 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
1.2. Binary Number System
Binary numbers consist of two digits – 0 and 1 referred to as binary digits, in short’ bits. In binary base
system, the positional value of a number increases by powers of two. When dealing with different number
systems, always remember to indicate the base of a binary number such as 1011 2.
Digital computers use a number system with a base of two, rather than base ten to represent any data. This
is because it is much easier to engineer circuits that implement “binary number system.” In groups,
discuss the four types of number systems and classify them according symbols used to represent any
number. If 1011 represents 11 in decimal form, represent decimal numbers 0 to 15 in binary form.
The octal number system also known as octadecimal has eight digits ranging from 0 – 7 that are used to
represent any number. This means that a number like 785 cannot be a valid octal number because 8 in
between 7 and 5 is not within 0 to 7 digits.
Hexadecimal is a base 16 number system consisting of 16 digits that range from 0 to 9, and A to F. The
letters A to F are used to represent numbers 10 to 15.
Below shows a summary of the four number systems classified according to their base values:
In groups of three, discuss the benefits and reasons for using octal
and hexadecimal number systems.
Mathematically, it is possible to convert a number from one base system to another. In the following
section, we demonstrate how to convert decimal numbers to other base systems.
To convert a decimal number to binary, there are two possible methods, the divisionremainder, and
positional-value methods.
Division-by-Base Method
In division-by-base method, a decimal number is repeatedly divided by the base until the dividend is
indivisible by 2. In every division, write down the remainder on the right of the dividend. Read the
sequence of 0s and 1s bottom-ups that represents the binary number. For example, to convert 45 10 to
binary form, proceed as follow:
NB: The remainder in the last division marked with asterisk is 1 because 1 is not perfectly divisible by 2
in the previous step.
Activity
Using division-by base method, convert the decimal number 247 to binary form. Confirm
whether is the 111101112 is correct answer.
The second method of converting decimal numbers to binary form is the place value method. For
example, to convert 24710 to binary form, proceed as follows:
1. Start by writing down the place values in powers of 2 up to the value equal to or slightly larger
than the number to be converted. For example, to convert 247 10 write down the place values up to
28.
2. Subtract the highest place value i.e 256 from the number. If the difference is 0 or positive, write 1,
otherwise write 0 if the difference is negative.
NB: Note that under the place value 2 8 , we write 0 because 247-256 returns a negative value.
3. If the difference returned a negative carry forward the number, the next lower significant place
value and calculate the difference. Since 247 – 128 returns 119 (positive), write 1.
4. Repeat the process until you encounter the least significant, until you subtract the previous step
difference from the least significant place value.
5. Read the binary digits from left to right. This gives us 011110111. Thus: 24710 = 0111101112.
To convert a decimal number to octal form, we repeatedly divide the dividend by the base value 8 until
the quotient is indivisible by 8. The remainders consisting of digits between 0 and 7 are read upwards. For
example, to convert 58610 to an octal number, proceed as follows:
To convert a decimal number to hexadecimal form, repeatedly divide the quotient by 16 until the quotient
is not divisible by the base value. The resulting remainders consisting of digits from 0-9, and A-F are read
bottom-up. For example, to convert a decimal number 896 to hexadecimal form, proceed as follows:
Explanation
Divide the number by 16 and write down the quotient and the remainder. Note the remainder can be a
digit between 0 and F.
Since hexadecimal symbols between 10 and 15 are represented by letters A to F, replace 15 with F and 13
with D in the remainders.
Conversion of a binary number to other base systems is the reverse procedure to what we have covered in
the previous section. In this section, we demonstrate how to convert binary numbers into decimal (base
10), octal (base 8) and hexadecimal (base 16) form.
1. Write place values under which you place the bits from the least significant to the most
significant.
2. Multiply each bit by corresponding place value e.g starting with most significant e.g in case of
101101, multiply the left most bit by 32. 3. Sum the partial products to get the decimal number
To convert a binary to Octal system group the One’s (1’s) and zero’s(0’s) into sets of three bits starting
from right to left. The reason for grouping into 3 bits is because the maximum octal digit (7) has a
maximum of 3 digits.
Thus: 0110100012=3218
Similar to the approach used with octal number system, a binary number can be converted to hexadecimal
format by grouping the bits to a set of 4 bits. This is because the largest hexadecimal digit i.e. F(15) has 4
bits.
For example, to convert 110100012 to hexadecimal form, group the bits into sets of 4 starting from right to
left as follows:
1. Split the number into sets of 4 bits starting from right to left. In our case, we get three complete sets
and one incomplete one:
11 0010 0001
2. Because the leftmost set has two bits, add two zeros to it on the left to get:
To convert octal numbers to decimal form, we use the division-by-base and place value methods used on
binary numbers. For example, to convert 5128 to decimal form, proceed as follows:
2. From left to right, multiply each digit by its place value as shown below:
Because octal to hexadecimal conversions cannot be done directly, we first convert given octal numbers to
its decimal or binary equivalent. In the second step we convert the decimal or binary number to its
hexadecimal equivalent.
1. To start with, we demonstrate how to use the two-stage approach to convert an octal number
10028 to hexadecimal:
Alternatively, you can convert an octal number to hexadecimal by converting the number to binary form
as follows:
1. First, write the place values starting from the right hand side.
3. Multiply each hexadecimal digit with its corresponding place value, and then add the partial products.
2. Multiply each hexadecimal digit with corresponding places value and write down the partial
products (256 × 1) + (16 × 1) + (1 × 1) downwards as follows:
In mathematics, a number with integer and fractional parts such as 87.25 is known as a real number. In
computing, a real number is referred to as floating point number.
The fractional part has a value that is less than 1 written as 1/x or 0.x. For example, 87.25 has a fractional
part 0.25 that may also be written as 1/4. The weight of a floating point number increases from right to
left.
In computing, the same approach is used to represent fractional binary numbers. For example, the
fractional binary number 11.110112 may be represented.
For example, to convert a number like 87.25 to binary form, first convert the integer part using one of the
methods discussed earlier. Then, convert the fractional part as follows:
2. Take the fractional part of the previous partial product and multiply it by 2. In our case: 0.50 × 2
= 1.000.
3. Repeat until the fractional part on the right of decimal point of the partial product is 0 or starts
recurring. For example, in step 2 above, the fractional part is 000 hence we stop.
4. Read downwards the 0s and 1s on the left of the decimal point of partial products as shown
below:
1. Convert the integer part 7 using the division-by 2 or place value method. The operation should return
111.
2. Convert the fractional part until the part on the right of decimal point is 0 or starts recurring:
3. Read the digits on the left of decimal point downwards as shown by the arrow. In this case, the digits
are 0.011.
In this example, we demonstrate how to convert a decimal number 0.40 that returns a recurring binary
fraction. We proceed as follows:
To convert a floating point binary number like 11.0112 to decimal form, proceed as follows:
1. Convert the bits on the left of the decimal point into decimal form and sum-up the partial
products as follows:
2. Next, convert the bits on the right of the decimal point to decimal form using corresponding place
values from left to right as shown below:
10
One’s complement is a temporary step to finding twos complement of a binary number. To convert a
binary number to ones complement, we invert 0 bits to 1s and vice versa. For example, the one’s
complement of 10011102 may be expressed as a unary operation as follows:
APPLY DATA STRUCTURE AND ALGORITHM 13 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
~(1001110) = 0110001; where ~ stands for negation.
Twos complement is another method used to represent negative numbers in binary form. Two’s
complement of a number is obtained by getting the one’s complement then adding 1 bit.
For example, to find the two’s complement of the binary number 10011102, proceed as follows:
~(1001110) = 0110001;
0110001 + 1 = 0110010
Introduction
As you may be aware, most modern computers are digital and they use binary logic to process data which
is represented as a series of 0’s and 1’s. In this chapter, we start by looking at simple logic circuits that
form the fundamental building blocks of data processing in computers. We then briefly look at Boolean
algebra and its connection to logic reasoning.
1. Logic gates
A logic gate is the basic building block of a digital circuit. A digital circuit is one that can only be in one
of two states at any one time, either ON or OFF. An ON means there is high voltage in the circuit while an
OFF means zero or no voltage in the circuit.
The input(s) can receive either ON or OFF signals usually represented by 1 or 0 then depending on the
logic within the gate, the output can either be 1 (one) or 0 (zero). 1.1. Basic logic gates
The truth tables are important because they help us to know the output of each individual gate given
certain inputs hence we can use them to construct more complex logic circuits that can solve real
problems.
Study the following logic circuit. Construct a truth table for the circuit.
2. Boolean algebra
Boolean algebra was invented by George Boole in 1654. It can be used to automate the manipulation of
objects that control real life processes. This is because computers are made up of digital switches that are
either ON or OFF. Since the inputs and outcomes of Boolean algebra are either 1 or 0, it is a more natural
way of representing digital information or computing logic. The algebra is used to explain or solve
problems related to logic and digital circuits.
Boolean operations revolve around Boolean operators. A Boolean operator takes two inputs of either 1 or
0 and output a single value also either 1 or 0.
There are several laws of boolean algebra. The most common operators that are used to manipulate the
various logic elements are the OR (+) and the AND(•)
e.g. A + B means A OR B.
5. Redundance law
1. Algorithm
Before developing a program, is it important that a programmer specifies the order in which the set of
instructions contained in the program are to be executed. This process of defining the step-by-step
procedure in which the instructions are to be executed is known as algorithm design.
The term algorithm was derived from the name of the 9 th century Persian mathematician and
astronomer Mohammed al-Khwarizmi. The concept has been adapted in computer science to refer to a
step-by-step procedure that specifies how to perform a task or solve a problem. Therefore, a computer
program is an algorithm implemented using a programming language.
To ensure that an algorithm produces desired solution, a programmer is tasked with the following roles:
A good algorithm is crucial to development of good computer programs. Some of the characteristics of
good algorithms include:
a. Finiteness: the algorithm stops after a finite number of instructions are executed.
b. Definiteness: Each step of an algorithm must be precisely defined; the actions to be
carried out must be rigorously and unambiguously specified for each case.
c. Input: the algorithm receives input. An algorithm has zero or more inputs, i.e,
quantities which are given to it initially before the algorithm begins.
d. Output: the algorithm produces output. An algorithm has one or more outputs i.e,
quantities which have a specified relation to the inputs.
e. Effectiveness: An algorithm is also generally expected to be effective. This means that all
of the operations to be performed in the algorithm must be sufficiently basic that they can
in principle be done exactly and in a finite length of time.
f. Precision – the steps are precisely stated (defined).
g. Uniqueness – results of each step are uniquely defined and only depend on the input and
the result of the preceding steps.
h. Generality – the algorithm applies to a set of inputs.
1.2. Role and Structure of algorithms
The role of algorithms is to support programmers in designing and implementing computer programs that
solve a problem of importance.
To solve such a problem, algorithm design follows a structured approach outlined below:
1. The programmer first analyses the problem to come up with problem Specification. A
problem specification defines input, processing and output required to solve the problem
APPLY DATA STRUCTURE AND ALGORITHM 18 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
2. Map the problem specification into an algorithm that defines the logic or procedure for solving
the problem.
3. Once an algorithm has been designed and tested against problem specifications, implement it as a
program using suitable programming languages.
4. Finally the program is installed on computers or portable devices to solve the problem.
1.3. Pseudocode
Pseudocode is a standard method of describing an algorithm without use of any specific programming
language. The word pseudo means that although pseudocode statements resemble real program code, it
cannot be executed by a computer. The purpose of pseudocode design is to help the programmers
formulate their thoughts on the organisation and sequence of a computer algorithm without the need of
following the actual coding syntax.
Although pseudocode is frequently used, there are no standard for its implementation. In most cases, we
borrow keywords such as PRINT, WRITE, INPUT, and READ from programming languages like
FORTRAN and Pascal to express an algorithm as a pseudocode.
To avoid ambiguity experienced with the use of natural languages, the following are basic rules to be
followed when writing pseudocode:
The following are some the advantages of using pseudocode to express an algorithm:
4. Pseudocode reduces time spent in coding, testing, and modifying a system. 5. Pseudocode implements
1.4. Flowcharts
The following are general rules that may be followed when expressing an algorithm using flowchart:
1. Be sure to use the right symbol for the right purpose. For examples it is wrong to use a terminal
symbol for input.
2. All the symbols of a flowchart should be connected using arrows (flow lines) and not plain lines.
3. The direction of flow should be from top to bottom, or sides depending on the page layout.
4. The start and end of a flowchart must be indicated with (start/stop) terminal symbol.
5. Flowchart should have only one entry point at the top and one exit point at the bottom or side.
6. The decision symbol should have only two exit points for either true or false on the sides, or
bottom and one side.
7. If a flowchart does not fit one page or column, use connectors to indicate breaks in the flowchart.
The following are some the advantages of using flowcharts to express an algorithm:
2. Variables
A variable can be defined as a name also known as identifier that represents data values which can
change.
The name given to variable is matter of choice by a programmer subject to the following rules:
1. Choose meaningful variable names that tell the reader of the program what the variable
represents. For example, use sum instead of just s.
2. Each variable in the same algorithm should be identified using a unique name. For example you
cannot use balls represent input, and balls to represent output
3. By convention, variable names should begin with a letter of the alphabet but may be followed by
numbers. For example, use balls3 instead of 3balls.
4. Avoid using variable names that may conflict with reserved or keywords used in most
programming languages.
5. Variable names made up of two or more words should not have space in between the words,
instead combine the two words or use an underscore. For example, instead of using Basic Salary
as variable name, use BasicSalary or Basic_salary.
Declaration of variable refers to identify and explicitly state input and output variables required to solve a
problem. For example, suppose you are required to solve a problem of finding sum and average of three
numbers. To identify and state input and output variable from the problem, proceed as follows:
1. Express the problem using natural language in order to identify input, processing and output
requirements as shown below:
NB: Variable names should not have spaces between words. Instead use an underscore to combine two
words or start the next work with uppercase.
3. Data types
In programming, data type determines the type of values that can be stored in a variable. Most
programming languages supports the following primary data types:
• Integers: Integers are whole numbers, which can either positive or negative including zero. For
example, 0, 5, -20, and 68 are integers.
• Real Numbers: These are numbers with a fractional part. Normally, the fractional part follows a
decimal point. For example, 68.67 is a real number.
• Character: Character data, sometimes referred to as “string” data, may consist of any digits,
letters of the alphabet or symbols which
• Boolean: Boolean data type is a type that can only take two values true or false.
Programming uses a number of different data types. A data type determines what type of value an object
can have and what operations can be performed.
Once a variable is declared it does not have a defined value, hence it cannot be used until it is initialised
by assigning it a value. Initialising a variable goes beyond declaration to assign an initial value to a
variable. For example, in our previous algorithm, we can initialise variables Num1, Num2, Num3 with
initial values as shown below:
Unlike a variable which is an identifier for values that can change, a constant is a fixed value which
cannot be changed.
Declaring a constant refers to specifying a symbolic name for a value that cannot be changed during
program execution.
A string constant is a sequence of characters such as “FRW 7200” that cannot be manipulated
mathematically while numeric constants such as 7200 can be manipulated in a mathematical
expressions. For example, to calculate area of a circle, we can declare π (pi) as a numeric (constant) as
follows: • const double PI= 3.142
To write correct mathematical expressions, you need to understand operators used in programming
languages namely: assignment, arithmetic, relational, and logical operators.
The assignment operators such as (=) or (:=) causes the operand on the left side of the operator to be
replaced by the value on the right side. For example, in the following expression, the value of x is
replaced by the sum of a and b. • x = a + b
Relational operators are used in boolean expressions that compares numeric or string constants and
returns a true or false. Such operators include: greater than (>), less than (<), equal to ( =), less than or
equal to (<=), greater than or equal to (>=), and not equal to (< >). Relational operators are binary
operators because they act on two operands e.g. 5>3 that returns true.
Logical operators derived from Boolean algebra are used on compound expressions or conditions to
return true or false. The three logical operators used in most programming languages are AND, OR
and NOT. Unlike AND and OR which are binary operators, NOT is a unary like tild (~) in mathematics.
This means that it negates the operand on its right side; e.g. NOT true returns false.
Bitwise operators are similar to logical operators only that they are specifically used to manipulate binary
digits. The main Bitwise operators are AND, inclusive OR, exclusive OR (XOR), NOT (~), binary left
shift (<<), and binary right shift (>>).
Precedence of operators refers to established rule that assigns priority of each operator used in an
expression. For example, when writing complex expressions in mathematics, we use precedence rule
known as BODMAS that stands for Brackets, Off, Division, Multiplication, Addition, and Subtraction.
BODMAS rule means that the highest priority is assigned to Bracket, with the lowest priority being
assigned to Subtraction. For example, in the expression below, unless we apply BODMAS rule, the
answer could be 6.5!
Like BODMAS in mathematics, we use precedence rule in algorithms to assign priority to each of the
arithmetic, relational and logical operators.
Table shows the order of precedence in each of the four categories from the highest to the lowest.
Functions are “self-contained” group of statements that accomplish a specific task. In algorithms, the read
function gets data from input devices like keyboard while write functions prints output on devices such as
screen.
1. Read functions
To represent read functions in an algorithm, we use keywords like READ, INPUT, and GET. For example,
the following statements demonstrate how to use read functions to get radius as input from keyword:
Good practice in algorithm design requires the READ functions to be in uppercase while values to be read
also known as parameters to be in lowercase. For clarity, if a function is to read several paramenters,
parenthesis may be used to enclose the parameters as shown below:
2. Write Functions
Like in read operations, we use keywords like WRITE, DISPLAY, and SHOW to represent functions that
display information on the screen. For example, the following statements demonstrate how to display area
on the screen:
For clarity, if a write function is to display several values, parenthesis may be used to enclose the
parameters as shown below:
1. Sequence
2. Branching(Selection)
3. Loop(Repetition)
According to the condition and requirement, these three control structures can be used.
In the sequence structure, statements are placed one after the other and the execution takes place starting
from up to down.
Whereas in branch control, there is a condition and according to a condition, a decision of either TRUE or
FALSE is achieved. In the case of TRUE, one of the two branches is explored; but in the case of FALSE
condition, the other alternative is taken. Generally, the ‘IF-THEN’ is used to represent branch control.
Example:
Write an algorithm to find the smallest number between two numbers Step1: Start
Step 6: End
Step1: Start
If NO then c=”even”
Step4: Display C
Step5: Stop
1. Selection/conditional structures
Conditional statements help you to make a decision based on certain conditions. Very often when you
write code, you want to perform different actions for different decisions. You can use conditional
statements in your code to do this. In all programming languages we have the following conditional
statements:
b. If/else statement
c. Nested if statement
d. If/Else If statement
Syntax
Start
If (condition) then
APPLY DATA STRUCTURE AND ALGORITHM 29 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
Instructions
End if
End
Use if/else to specify a block of code to be executed, if the same condition is false
Syntax
Start
If (condition) then
Instructions
Else
Instructions
End if
End
Use else/if to specify a new condition to test, if the first condition is false.
Syntax
Start
If (condition) then
Instructions
Instructions
Instructions
Else [optional]
APPLY DATA STRUCTURE AND ALGORITHM 30 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
Instructions
End if
End
Syntax
Start
If (condition)
If (condition) then
Instructions
Else
Instructions
End if
Else [optional]
Instructions
End if
End
a. A program that checks the age and display a decision if someone is eligible to be
hired.
b. A program that checks the age and displays a decision if someone is eligible to be
hired or not.
c. A program that takes or read three numbers from the user and print the greatest
number.
d. A program that helps a trainer to grade students according to their percentage
marks results.
Results % Grade
0-10 F
11-30 E
31-50 D
51-70 C
71-90 B
91-100 A
2. Sequence structures
A sequential statement or switch case statement or simply switch statement tests the value of a variable
and compares it with multiple cases. Once the case match is found, a block of statements associated with
that particular case is executed.
Each case in a block of a switch has a different name which is referred to as an identifier. The value
provided by the user or initialized is compared with all the cases inside the switch block until the match is
found.
Syntax
Block-1;
Break; case
value-2:
Block-2;
Block-n;
Break; default:
Block-1;
Break;
Statement-x;
Write algorithm pseudocodes and flowchart of the following programs:
1) Write algorithm pseudocodes of a program that accepts a grade and displays the
equivalent description:
Grade Description
E Excellent
V Very Good
G Good
A Average
F Fail
4) Write a program that will ask the user to enter two integer numbers and a
simple 4-cases calculator program that might prompt the user by providing the following
menu:
Please enter:
This menu will display the result according to the choice of the user.
3. Looping/iterating structures
A loop is a sequence that gets executed several times. A complete execution of a sequence is called an
iteration of the loop.
A for-loop has two parts: a header specifying the iteration, and a body which is executed once per
iteration. The header often declares an explicit loop counter or loop variable, which allows the body to
know which iteration is being executed. For-loops are typically used when the number of iterations is
known before entering the loop.
The while construct consists of a block of code and a condition/expression. The condition/expression is
evaluated, and if the condition/expression is true, the code within the block is executed. This repeats
until the condition/expression becomes false.
Because the while loop checks the condition/expression before the block is executed, the control structure
is often also known as a pre-test loop.
Syntax in JavaScript
Starting value; do
while (testExpression);
condition; increment/decrement)
statement(s);
initialization;
while (condition1)
{
statement(s);
while (condition2)
{
statement(s);
APPLY DATA STRUCTURE AND ALGORITHM 35 Prepared by Fidel NDAYISHIMIYE
USING JAVASCRIPT
... ... ...
} ... ... ...
}
12
123
1234
12345
2.1 Data structure concepts are clearly identified based on intended use.
A data structure is a technique of storing and organizing the data in such a way that the data can be
utilized in an efficient manner.
Example: Library is composed of elements (books) to access a particular book requires knowledge
of the arrangement of the books.
Traversing: Accessing each record exactly once so that certain items in the record may be processed.
Searching: Finding the location of the record with a given key value or finding the locations of
all records which satisfy one or more conditions Inserting: Adding a new record to the
structure.
Deleting: Removing a record from the structure.
Sorting: Arranging the records in some logical order (e.g., in numerical order according to some
NUMBER key, such as social security number or account number).
Merging: Combining the records of two different sorted lists into a single sorted list.
A linear data structure is a structure in which the elements are stored sequentially, and the elements are
connected to the previous and the next element. As the elements are stored sequentially, so they can be
traversed or accessed in a single run.
The types of linear data structures are Array, Queue, Stack, Linked List.
Array: An array consists of data elements of the same data type. For example, if we want to store the roll
numbers of 10 students, so instead of creating 10 integer type variables, we will create an array having
size 10.
Therefore, we can say that an array saves a lot of memory and reduces the length of the code.
Stack: It is linear data structure that uses the LIFO (Last in First Out) rule in which the data added last
will be removed first. The addition of data element in a stack is known as a push operation, and the
deletion of data element from the list is known as pop operation.
Queue: It is a data structure that uses the FIFO (First In First Out). In this rule, the element which is added
first will be removed first.
There are two terms used in the queue front and rear. The insertion operation performed at the back end is
known enqueue, and the deletion operation performed at the front end is known as dequeue.
Linked List: It is a collection of nodes that are made up of two parts, data element and reference to the
next node in the sequence.
A non-linear data structure is also another type of data structure in which the data elements are not
arranged in a contiguous manner. As the arrangement is nonsequential, so the data elements cannot be
traversed or accessed in a single run. In the case of linear data structure, element is connected to two
elements (previous and the next element), whereas, in the non-linear data structure, an element can be
connected to more than two elements.
o Tree
It is a non-linear data structure that consists of various linked nodes. It has a hierarchical tree structure
that forms a parent-child relationship. The diagrammatic representation of a tree data structure is shown
below:
o Graph
A graph is a non-linear data structure that has a finite number of vertices and edges, and these edges are
used to connect the vertices. The vertices are used to store the data elements, while the edges represent the
relationship between the vertices. A graph is used in various real-world problems like telephone networks,
circuit networks, social networks like LinkedIn, Facebook. In the case of facebook, a single user can be
considered as a node, and the connection of a user with others is known as edges.
Linear Data structure Non-Linear Data structure
Types Arrays, linked list, stack, queue Trees and graphs are the types of a nonlinear data
are the types of a linear data structure.
structure.
Traversal
As linear data structure is a single The data items in a non-linear data structure
level, so it requires a single run to cannot be accessed in a single run. It requires
traverse each data item. multiple runs to be traversed.
Time complexity The time complexity of linear data The time complexity of non-linear data structure
structure increases with the often remains same with the increase in the input
increase in the input size. size.
Applications
Linear data structures are mainly Non-linear data structures are used in image
used for developing the software. processing and Artificial Intelligence.
Levels This data structure does not In this, the data elements are arranged in multiple
contain any hierarchy, and all the levels.
data elements are organized in a
single level.
2.2 Linear Data Structures are properly applied based on their operational
Complexity
Arrays hold a series of data elements, usually of the same size and data type. Individual elements
are accessed by their position in the array. The position is given by an index, which is also called a
subscript.
Some arrays are multi-dimensional, meaning they are indexed by a fixed number of integers, for example
by a tuple of four integers. Generally, one- and two-dimensional arrays are the most common. Most
programming languages have a built-in array data type.
In computer programming, a group of homogeneous elements of a specific data type is known as an array,
one of the simplest data structures.
1. Arrays dimensions
A dimension of array is a direction in which you can vary the specification of an array’s elements. An
array can be of one or many dimensions.
a. One-dimensional array
Example: a [3]
It is an array called a with 3 elements. The elements of the array are logically represented by the
name of the array with in brackets its index or positions. For the one dimensional array a with 3 elements,
elements are written like a[0], a[1] and a[2]. The indexes start always by 0. Graphically, it is:
JavaScript array is an object that represents a collection of similar type of elements. There are 3 ways to
construct array in JavaScript
1. By array literal
2. By creating instance of array directly (using new keyword)
3. By using an array constructor (using NEW keyword)
Syntax:
Var arrayname=[value1, value2,….valueN];
Example:
<script>
Var emp=[“Alice”,”Aline”,”Alain”];
For(i=0;i<emp.length;i++)
{
Document.write(emp[i]+”<br>”);
}
</script>
Syntax:
<script>
Var i;
For(i=0;i<emp.length;i++)
{
Document.write(emp[i]+”<br>”);
}
</script>
Example:
Var emp=new Array(“Jai”, “Valens”, “John”);
For(i=0;i<emp.length;i++)
{
Document.write(emp[i]+”<br>”);
}
</script>
Let's see the list of JavaScript array methods with their description.
Methods Description
concat() It returns a new array object that contains two or more merged arrays.
copywithin() It copies the part of the given array with its own elements and returns the modified
array.
entries() It creates an iterator object and a loop that iterates over each key/value pair.
every() It determines whether all the elements of an array are satisfying the provided
function conditions.
flat() It creates a new array carrying sub-array elements concatenated recursively till the
specified depth.
flatMap() It maps all array elements via mapping function, then flattens the result into a new
array.
from() It creates a new array carrying the exact copy of another array element.
filter() It returns the new array containing the elements that pass the provided function
conditions.
find() It returns the value of the first element in the given array that satisfies the specified
condition.
findIndex() It returns the index value of the first element in the given array that satisfies the
specified condition.
forEach() It invokes the provided function once for each element of an array.
includes() It checks whether the given array contains the specified element.
indexOf() It searches the specified element in the given array and returns the index of the first
match.
keys() It creates an iterator object that contains only the keys of the array, then loops
through these keys.
lastIndexOf() It searches the specified element in the given array and returns the index of the last
match.
map() It calls the specified function for every array element and returns the new array
of() It creates a new array from a variable number of arguments, holding any type of
argument.
reduce(function, It executes a provided function for each value from left to right and reduces the
initial) array to a single value.
reduceRight() It executes a provided function for each value from right to left and reduces the
array to a single value.
some() It determines if any element of the array passes the test of the implemented function.
slice() It returns a new array containing the copy of the part of the given array.
sort() It returns the element of the given array in a sorted order.
toString() It converts the elements of a specified array into string form, without affecting the
original array.
unshift() It adds one or more elements in the beginning of the given array.
values() It creates a new iterator object carrying values for each index in the array.
b. Multi-dimensional arrays
Example:
Two dimensional array ex: a[2][7]as Integer
Three dimensional array ex: a[3][2][5]as Integer
A Two dimensional Array is a collection of a fixed number of elements (components) of the same type
arranged in two dimensions.
The two dimensional array is also called a matrix or a table. The intersection of a column and a row is called
a cell. The numbering of rows and columns starts by 0
Example:
The array a[3][4] is an array of 3 rows and 4 columns. In matrix representation, it looks like the following:
a[i][j] means that it is an element located at the intersection of row i and column j. Each element is
identified by its row and column.
Syntax:
SET Array name=Array [row size][column size] of Data type
Examples:
1. SET a=Array[2][7] of Integer
2. SET b=Array[4][3] of Integer
When a two-dimension array has been declared, it needs to be assigned values for its elements. This
action of assigning values to array elements is called initialization. Two-Dimensional array is initialized
by specifying bracketed values for each row. For the case of array of integers, the default values of each
element is 0 while for others the default values for other types is not known.
For the case of an array of 3 rows and 4 columns, if the name is A and the type of elements is integer, the
initialization is:
The two dimensional array marks which will hold 12 elements can be initialized like:
BEGIN
SET marks=Array[3] [4] of Integer
marks[0][0]=18 marks[0][1]=16
marks[0][2]=14 marks[0][3]=19
marks[1][0]=10 marks[1][1]=20
marks[1][2]=12 marks[1][3]=15
marks[2][0]=15 marks[2][1]=17
marks[2][2]=18 marks[2][3]=16
END
BEGIN
SET marks=Array[3] [4] of Integer
For i=0 To 2 DO
For j=0 To 3 DO
READ marks[i][j]
NEXT j
END FOR
NEXT i
END FOR
END
Accessing two dimensional array elements
Syntax:
FOR i=initial value TO upperlimit DO
FOR j=initial value TO upperlimit DO
READ array name[i][j] i=i+1 j=j+1
Example: Write an algorithm of a program that allows the user to enter (store) two dimensional array elements
BEGIN
SET marks=Array [3] [8] of Integer
Use variable i as integer
Use variable j as integer
FOR i=0 TO 2 DO
FOR j=0 TO 7 DO READ
marks[i] [j]
i=i+1 j=j+1
END FOR
END FOR
END
Where i refers to the row position and j refers to the column position. Initial value=lower
limit
syntax:
WRITE Array name [i][j]
Example: Write an algorithm of a program that displays stored two dimensional array marks’ elements
BEGIN
SET a=Array[3][8] of integer
Use variable i As integer
Use variable j As integer
WRITE “stored two dimensional array elements are:”
FOR i=0 to 2DO
FOR j=0 to 7DO
WRITE a[i][j] i=i+1
j= j+1
END FOR
END FOR
END
Activity
A list is a collection of data in which each element of the list contains the location of the next element.
In a list, each element contains two parts: data and link to the next element. The data parts of the list hold
the value information and data to be processed. The link part of the list is used to chain the data together
and contains a pointer (an address) that identifies the next element in the list.
Example of a list:
A bank has 10 branches created one after another at different dates. The Bank Inspector who
wants to visit all of them can follow the order of their creation. He/she will be informed only about the
name and location of the first branch. When he reaches that branch, the Branch Manager will tell him/her
the address of the next branch, and so one.
After visiting all branches, the Bank Inspector will realize that he/she has a list of the bank branches.
Graphically, it will be represented like a list where each branch is considered as a node containing the names of
the branch and the address of the next branch.
A list is an ordered set of data. It is often used to store objects that are to be processed sequentially.
An array is an indexed set of variables, such as dancer [1], dancer [2], dancer [3] It is like a set of boxes
that hold things. A list is a set of items. An array is a set of variables that each store an item.
In a list, the missing spot is filled in when something is deleted. While in an array, an empty variable is
left behind when something is deleted. Simply a list is a sequence of data, and linked list is a sequence of
data linked with each other.
This is a dynamic table/ data structure used to hold a sequence. Its characteristics are the following:
• Items forming a sequence are not necessarily held in contiguous data location or in the order in
which they occur in the sequence.
• Each item in the list is called a node and contains an information field and a new address field
called a link or pointer field.
• Information field holds actual data for list item; link field contains the address of the next item.
• The link field in the last item indicates that there are not further items.
E.g. has a value of 0.
• Associated with the list is a pointer variable which points to the first node in the list.
• We use linked list in linking files, for example, in a hard disk.
• It can grow or shrink in size during execution of a program. • It can be made just as long as
required
• It does not waste memory space.
Single linked list is a sequence of elements in which every element has link to its next element in the sequence.
In any single linked list, the individual element is called as “Node”. Every “Node” contains two fields,
data and next. The data field is used to store actual value of that node and next field is used to store the
address of the next node in the sequence.
In a single linked list, the address of the first node is always stored in a reference node known as “front”
(Sometimes it is also known as “head”). Always next part (reference part) of the last node must be NULL)
BEGIN
struct node{ int
info
struct node next } head,
current, temp
head=null temp=null
current=null
Begin sub
Step 1 Read the element into x
Step 2 Create a temp node in the memory temp =(struct
node )sizeof (node)
Step 3 Assign the values in temp node as follows temp ->
info =x temp ->next=null
End sub
END
We can use the following steps to insert a new node after a node in the single linked list
Step 1: Create a newNode with given value.
• Step 2: Check whether list is Empty (head == NULL)
• Step 3: If it is Empty then, set newNode => next = NULL and head = newNode.
• Step 4: If it is Not Empty then, define a node pointer temp and initialize with head.
• Step 5: Keep moving the temp to its next node until it reaches to the node after which we want
to insert the newNode (until temp1 => data is equal to location, here location is the node value
after which we want to insert the newNode).
• Step 6: Every time check whether temp is reached to last node or not. If it is reached to last node
then display ‘Given node is not found in the list!!! Insertion not possible!!!’ and terminate the
function. Otherwise move the temp to next node.
• Step 7: Finally, Set ‘newNode => next = temp => next’ and ‘temp => next= newNode’
We can use the following steps to delete a specific node from a single linked list
• Step 1: Check whether list is Empty (head == NULL)
• Step 2: If it is Empty then, display ‘List is Empty!!! Deletion is not possible’ and terminate the
function.
• Step 3: If it is Not Empty then, define two Node pointers ‘temp1’ and ‘temp2’ and initialize
‘temp1’ with head.
• Step 4: Keep moving the temp1 until it reaches to the exact node to be deleted or to the last
node. And every time set ‘temp2 = temp1’ before moving the ‘temp1’ to its next node.
• Step 5: If it is reached to the last node then display ‘Given node not found in the list! Deletion
not possible!!!’ And terminate the function.
• Step 6: If it is reached to the exact node which we want to delete, then check whether list is
having only one node or not
• Step 7: If list has only one node and that is the node to be deleted, then set head = NULL and
delete temp1 (free (temp1)).
• Step 8: If list contains multiple nodes, then check whether temp1 is the first node in the list
(temp1 == head).
• Step 9: If temp1 is the first node then move the head to the next node (head = head => next) and
delete temp1.
• Step 10: If temp1 is not first node then check whether it is last node in the list (temp1=> next ==
NULL).
• Step 11: If temp1 is last node then set temp2 => next = NULL and delete temp1 (free (temp1)).
• Step 12: If temp1 is not first node and not last node then set temp2 => next = temp1=> next and
delete temp1 (free (temp1)).
We can use the following steps to display the elements of a single linked list
• Step 1: Check whether list is Empty (head == NULL)
• Step 2: If it is Empty then, display ‘List is Empty!!!’ and terminate the function.
• Step 3: If it is Not Empty then, define a Node pointer ‘temp’ and initialize with head.
• Step 4: Keep displaying temp=> data with an arrow (->) until temp reaches to the last node
• Step 5: Finally display temp => data with arrow pointing to NULL (temp => data -> NULL).
Double linked list is a sequence of elements in which every element has links to its previous element and next
element in the sequence.
So, we can traverse forward by using next field and can traverse backward by using previous field. Every
node in a double linked list contains three fields and they are shown in the following figure:
We can use the following steps to insert a new node after a node in the double linked list
• Step 1: Create a newNode with given value.
• Step 2: Check whether list is Empty (head == NULL)
• Step 3: If it is Empty then, assign NULL to newNode => previous&newNode => next and
newNode to head.
• Step 4: If it is not Empty then, define two node pointers temp1&temp2 andinitialize temp1 with
head.
• Step 5: Keep moving the temp1 to its next node until it reaches to the node after which we want
to insert the newNode (until temp1 => data is equal to location, here location is the node value
after which we want to insert the newNode).
• Step 6: Every time check whether temp1 is reached to the last node. If it is reached to the last
node then display ‘Given node is not found in the list!!! Insertion not possible!!!’ and
terminate the function. Otherwise move the temp1 to next node.
• Step 7: Assign temp1 => next to temp2, newNode to temp1=> next, temp1 to newNode =>
previous, temp2 to newNode => next and newNode to temp2 =>previous.
We can use the following steps to delete a specific node from the double linked list
• Step 1: Check whether list is Empty (head == NULL)
• Step 2: If it is Empty then, display ‘List is Empty!!! Deletion is not possible’ and terminate the
function.
• Step 3: If it is not Empty, then define a Node pointer ‘temp’ and initialize with head.
• Step 4: Keep moving the temp until it reaches to the exact node to be deleted or to the last node.
• Step 5: If it is reached to the last node, then display ‘Given node not found in the list! Deletion
not possible!!!’ and terminate the fuction.
• Step 6: If it is reached to the exact node which we want to delete, then check whether list is
having only one node or not
• Step 7: If list has only one node and that is the node which is to be deleted then set head to
NULL and delete temp (free(temp)).
• Step 8: If list contains multiple nodes, then check whether temp is the first node in the list (temp
== head).
• Step 9: If temp is the first node, then move the head to the next node (head = head => next), set
head of previous to NULL (head => previous = NULL) and delete temp.
• Step 10: If temp is not the first node, then check whether it is the last node in the list (temp =>
next == NULL).
• Step 11: If temp is the last node then set temp of previous of next to NULL (temp => previous
=> next = NULL) and delete temp (free(temp)).
Step 12: If temp is not the first node and not the last node, then set temp of previous of next to
temp of next (temp => previous => next = temp => next), temp of next of previous to temp of
previous (temp => next => previous =temp => previous) and delete temp (free(temp)).
We can use the following steps to display the elements of a double linked list
• Step 1: Check whether list is Empty (head == NULL)
• Step 2: If it is Empty, then display ‘List is Empty!!!’ and terminate the function.
• Step 3: If it is not Empty, then define a Node pointer ‘temp’ and initialize with head.
• Step 4: Display ‘NULL <= ‘.
• Step 5: Keep displaying temp → data with an arrow () until temp reaches to the last node
• Step 6: Finally, display temp → data with arrow pointing to NULL (tem→ data ---> NULL).
We can use the following steps to insert a new node after a node in the circular linked list...
We can use the following steps to display the elements of a circular linked list
• Step 1: Check whether list is Empty (head == NULL)
• Step 2: If it is Empty, then display ‘List is Empty!!!’ and terminate the function.
• Step 3: If it is Not Empty then, define a Node pointer ‘temp’ and initialize with head.
• Step 4: Keep displaying temp → data with an arrow (--->) until temp reaches to the last node
• Step 5: Finally display temp → data with arrow pointing to head → data.
2.2.4. Queue
A queue is a linear list in which data can only be inserted at one end, called the REAR, and deleted from the
other end, called the FRONT.
These restrictions ensure that the data is processed through the queue in the order in which it is received.
In an other words, a queue is a structure in which whatever goes first comes out first (first in, first
out(FIFO) structure).
1. Types of queues
There exist two types of queues:
• Linear queue
• Circular queue
a. Linear Queue
Queue data structure is a linear data structure in which the operations are performed based on
FIFO principle. Queue Operations using Array before we implement actual operations, first follow the
below steps to create an empty queue.
• Step 1: Include all the header files which are used in the program and define a constant ‘SIZE’
with specific value.
• Step 2: Declare all the user defined functions which are used in queue implementation.
• Step 3: Create a one dimensional array with above defined SIZE ( int queue[SIZE])
• Step 4: Define two integer variables ‘front’ and ‘rear’ and initialize both with ‘-1’. (int front = -
1, rear = -1)
• Step 5: Then implement main method by displaying menu of operations list and make suitable
function calls to perform operation selected by the user on queue.
b. Circular Queue
Circular Queue is a linear data structure in which the operations are performed based on FIFO
(First In First Out) principle and the last position is connected back to the first position to make a circle.
To implement a circular queue data structure using array, we first create it.
• Step 1: Include all the header files which are used in the program and define a constant
‘SIZE’ with specific value.
• Step 2: Declare all user defined functions used in circular queue implementation.
• Step 3: Create a one dimensional array with above defined SIZE (int cQueue[SIZE])
• Step 4: Define two integer variables ‘front’ and ‘rear’ and initialize both with ‘-1’. (int front = -
1, rear = -1)
• Step 5: Implement main method by displaying menu of operations list and make suitable
function calls to perform operation selected by the user on circular queue.
2. Queue operations
2.2.5. Stack
A stack is a restricted linear list in which all additions and deletions are made at one end, the top. If we
insert a series of data items into a stack and then remove them, the order of the data is reversed. Data
input as 5, 10, 15, 20, for example would be removed as 20, 15, 10, and 5. This reversing attribute is why
stacks are known as Last in, First out (LIFO) data structures.
We use many different types of stacks in our daily lives. We often talk of a stack of coins, stack of books on a
table and stack of plates in a kitchen.
Any situation in which we can only add or remove an object at the top is a stack. If we want to remove an
object other than the one at the top, we must first remove all objects above it. The following charts
illustrates cases of stack
A Stack is a Last in First out (LIFO) dynamic table or data structure. It has the following characteristics:
• List of the same kind of elements;
• Addition and deletion of elements occur only at one end, called the top of the stack;
• Computers use stacks to implement method calls;
• Stacks are also used to convert recursive algorithms into non recursive algorithm.
Before implementing actual operations, first follow the below steps to create an empty stack.
• Step 1: Include all the header files which are used in the program and define a constant ‘SIZE’
with specific value.
• Step 2: Declare all the functions used in stack implementation.
• Step 3: Create a one dimensional array with fixed size (int stack[SIZE])
• Step 4: Define a integer variable ‘top’ and initialize with ‘-1’. (top = -1)
• Step 5: In main method display menu with list of operations and make suitable function calls to perform
operation selected by the user on the stack.
2. Stack exceptions
Adding an element to a full stack and removing an element from an empty stack would generate errors or
exceptions:
• Stack overflow exception: it occurs if you try to add an item to stack or queue which is already
full.
• Stack underflow exception: it occurs if you try to remove an item from an empty queue or
stack.
Exercises
2.2.5. Searching and sorting using complex data structure.
Searching is the process of finding the location of a given element in a set of elements.
Searching means to find whether a particular value is present in an array or not. If the value is present in
the array, then searching is said to be successful and the searching process gives the location of that value
in the array.
Linear search: This method traverses a list sequentially to locate the search key. Binary search: This
method works on sorted lists by progressively making better guesses to find the location of a search key.
The linear search is also called sequential search. It is a simple method used for searching an array
for a particular value. It works by comparing the value to be searched with every element of the
array one by one in a sequence until a match is found.
Notice that the linear search is mostly used to search in an unordered list of elements Linear Search Algorithm
2. Binary Search
You search an array by repeatedly dividing the search interval in half. While dividing you begin with an
interval covering the whole array. If the value of the search key is less than the item in the middle of the
interval, narrow the interval to the lower half. Otherwise narrow it to the upper half. Repeatedly check
until the value is found or the interval is empty. This kind of search is also called the dichotomy method
or bisection method. It is possible on sorted array.
Note:
• “a ” is an array of the size n.
• “n” is the size of the array “a”
• “ item ” is the element to find in the array “a”.
• “loc” is the index of the element in the array “a”. Begin set beg=0 set end=n-1
set mid=(beg+end)/2 while((beg<=end) and(a[mid]!=item) do if(item<a[mid]) then
set end=mid-1
else set
beg=mid+1
endif
set mid=(beg+end)/2
endwhile if(beg>end)
then set loc=-1 else set
loc=mid endif
end
Sorting is the process of arranging elements in some logical order either in ascending or descending order.
There are various methods for sorting in this section that we are going to discuss:
Selection Sort
Bubble Sort
Insertion Sort
Merge Sort
Quick Sort
Shell Sort
Heap Sort
Radix Sort
Counting Sort
Bucket Sort
Bubble Sort is a simple-minded algorithm based on the idea that we look at the list, and wherever we find
two consecutive elements out of order, we swap them. This is done as follows: Repeatedly traverse the
unsorted part of the array by comparing consecutive elements, and interchange them when they are out of
order.
The Insertion Sort is a comparison-based algorithm that builds a final sorted array one element at a time.
It iterates through an input array and removes one element per iteration, finds the place if the element
belongs in the array, and then places it there.
Begin
For I = 1 to N-1
J=I
Do while (J > 0) and (A(J) < A(J - 1)
Temp = A(J)
A(J) = A(J - 1)
A(J - 1) = Temp
J=J-1
End-Do
End-For
End
The Selection Sort is a simplicity sorting algorithm. Here are basic steps of selection sort algorithm: o
Find the minimum element in the list
o Swap it with the element in the first position of the list
o Repeat the steps above for all remainder elements of the list starting at the second position.
The idea of Selection Sort is that we repeatedly find the smallest element in the unsorted part of the array
and swap it with the first element in the unsorted part of the array.
Definition
Non linear data structure is a form of data structure where the data elements do not stay arranged linearly or
sequentially.
Since the data structure is non linear, it does not involve a single level. Therefore, a user can not traverse all of
its elements in a single run.
2.3.1. Tree
Tree is a very popular data structure used in wide range of applications. A tree data structure can be defined as
follows.
In a tree data structure, if we have N number of nodes then we can have a maximum of N-1 number of links.
Tree data structure is a collection of data (Node) which is organized in hierarchical structure and this is a
recursive definition.
1. Tree Terminology
a. Root
In a tree data structure, the first node is called as Root Node. Every tree must have root node..
b. Edge
In a tree data structure, the connecting link between any two nodes is called an Edge. In a tree with ‘N’
number of nodes there will be a maximum of ‘N-1’ number of edges.
c. Parent
In a tree data structure, the node which is predecessor of any node is called a PARENT NODE.
In simple words, the node which has branch from it to any other node is called as parent node.
d. Child
In a tree data structure, the node which is descendant of any node is called a CHILD Node. In a tree, any
parent node can have any number of child nodes. In a tree, all the nodes except root are child nodes.
e. Siblings
In a tree data structure, nodes which belong to same Parent are called SIBLINGS.
f. Leaf
In a tree data structure, the node which does not have a child is called a LEAF Node. In a tree data
structure, the leaf nodes are also called a External Nodes or Terminal node.
g. Degree
In a tree data structure, the total number of children of a node is called as DEGREE of that Node. In
simple words, the Degree of a node is total number of children it has. The highest degree of a node among
all the nodes in a tree is called as ‹Degree of Tree’
h. Level
In simple words, in a tree each step from top to bottom is called as a
Level and the Level count starts with ‘0’ and incremented by one at each level (Step).
i. Height
In a tree data structure, the total number of edges from leaf node to a particular node in the longest path is
called as HEIGHT of that Node. In a tree, height of the root node is said to be height of the tree. In a tree,
height of all leaf nodes is ‘0’.
j. Depth
In a tree data structure, the total number of edges from root node to a particular node is called DEPTH of
that Node. In a tree, the total number of edges from root node to a leaf node in the longest path is said to
be Depth of the tree. In a tree, depth of the root node is ‘0’.
k. Path
In a tree data structure, the sequence of Nodes and Edges from one node to another node is called as PATH
between those two Nodes.
l. Sub Tree
In a tree data structure, each child from a node forms a sub tree recursively. Every child node will form a sub-
tree on its parent node.
A binary tree data structure is represented using two methods. Those methods are as follows:
Consider a Binary Tree T. T will be maintained in memory by means of a linked list representation,
which uses three parallel arrays; INFO, LEFT, and RIGHT pointer variable ROOT as follows. In
Binary Tree, each node N of T will correspond to a location k such that:
Representation of a node:
Example
Consider the binary tree T in the figure of Binary Tree
For Example:
Consider the following Tree:
b. Binary Tree Traversals
When we wanted to display a binary tree, we need to follow some order in which all the nodes of that
binary tree must be displayed. In any binary tree displaying order of nodes depends on the traversal
method.
Displaying (or) visiting order of nodes in a binary tree is called as Binary Tree Traversal.
a. In-order Traversal
In this traversal method, the left sub tree is visited first, then the root and later the right sub-tree. We
should always remember that every node may represent a sub tree itself.
If a binary tree is traversed in-order, the output will produce sorted key values in an ascending order.
We start from A, and following in-order traversal, we move to its left subtree B. B is also traversed in-
order. The process goes on until all the nodes are visited. The output of inorder traversal of this tree will
be:
D→B→E→A→F→C→G
Algorithm:
b. Pre-order Traversal
In this traversal method, the root node is visited first, then the left subtree and finally the right subtree.
A→B→D→E→C→F→G
Algorithm:
c. Post-order Traversal
In this traversal method, the root node is visited last, hence the name. First we traverse the left sub
tree, then the right sub tree and finally the root node.
D→E→B→F→G→C→A
Algorithm:
Binary Search tree exhibits a special behavior. A node’s left child must have a value less than its parent’s
value and the node’s right child must have a value greater than its parent value.
A Binary Search Tree (BST) is a tree in which all the nodes follow the below-mentioned properties
• The left sub-tree of a node has a key less than or equal to its parent node’s key.
• The right sub-tree of a node has a key greater than to its parent node’s key.
Thus, BST divides all its sub-trees into two segments; the left sub-tree and the right sub-tree and can be defined
as
Basic Operations
Following are the basic operations of a tree −
• Search − Searches an element in a tree.
• Insert − Inserts an element in a tree.
• Pre-order Traversal − Traverses a tree in a pre-order manner.
• In-order Traversal − Traverses a tree in an in-order manner.
• Post-order Traversal − Traverses a tree in a post-order manner.
Exercises
2.3.2. Graph
1. Introduction
A Graph is a non-linear data structure consisting of vertices and edges. The vertices are sometimes also
referred to as nodes and the edges are lines or arcs that connect any two nodes in the graph.
More formally a Graph is composed of a set of vertices( V ) and a set of edges( E ). The graph is denoted by G(E,
V).
Graphs are used to solve many real-life problems. Graphs are used to represent networks. The networks
may include paths in a city or telephone network or circuit network. Graphs are also used in social
networks like linkedIn, Facebook. For example, in Facebook, each person is represented with a vertex(or
node). Each node is a structure and contains information like person id, name, gender, locale etc.
2. Representations of Graph
Here are the two most common ways to represent a graph :
• Adjacency Matrix
• Adjacency List
Adjacency Matrix
An adjacency matrix is a way of representing a graph as a matrix of boolean (0’s and
1’s).
Let’s assume there are n vertices in the graph So, create a 2D matrix adjMat[n][n] having dimension n x n.
The below figure shows an undirected graph. Initially, the entire Matrix is initialized to 0. If there is an
edge from source to destination, we insert 1 to both cases (adjMat[destination] and adjMat[destination])
because we can go either way.
Representation of Directed Graph to Adjacency Matrix:
The below figure shows a directed graph. Initially, the entire Matrix is initialized to 0. If there is an edge
from source to destination, we insert 1 for that particular adjMat[destination].
Adjacency List
An array of Lists is used to store edges between two vertices. The size of array is equal to the number of
vertices (i.e, n). Each index in this array represents a specific vertex in the graph. The entry at the index i
of the array contains a linked list containing the vertices that are adjacent to vertex i.
Let’s assume there are n vertices in the graph So, create an array of list of size n as adjList[n].
• adjList[0] will have all the nodes which are connected (neighbour) to vertex 0.
• adjList[1] will have all the nodes which are connected (neighbour) to vertex 1 and so on.
The below directed graph has 3 vertices. So, an array of list will be created of size 3, where each indices
represent the vertices. Now, vertex 0 has no neighbours. For vertex 1, it has two neighbour (i.e, 0 and 2)
So, insert vertices 0 and 2 at indices 1 of array. Similarly, for vertex 2, insert its neighbours in array of list.
3. Types of Graphs
1. Undirected Graphs: A graph in which edges have no direction, i.e., the edges do not have arrows
indicating the direction of traversal. Example: A social network graph where friendships are not
directional.
2. Directed Graphs: A graph in which edges have a direction, i.e., the edges have arrows indicating the
direction of traversal. Example: A web page graph where links between pages are directional.
3. Weighted Graphs: A graph in which edges have weights or costs associated with them. Example: A
road network graph where the weights can represent the distance between two cities.
4. Unweighted Graphs: A graph in which edges have no weights or costs associated with them. Example:
A social network graph where the edges represent friendships.
5. Complete Graphs: A graph in which each vertex is connected to every other vertex. Example: A
tournament graph where every player plays against every other player.
6. Bipartite Graphs: A graph in which the vertices can be divided into two disjoint sets such that every
edge connects a vertex in one set to a vertex in the other set. Example: A job applicant graph where
the vertices can be divided into job applicants and job openings.
7. Trees: A connected graph with no cycles. Example: A family tree where each person is connected to
their parents.
8. Cycles: A graph with at least one cycle. Example: A bike-sharing graph where the cycles represent the
routes that the bikes take.
9. Sparse Graphs: A graph with relatively few edges compared to the number of vertices. Example: A
chemical reaction graph where each vertex represents a chemical compound and each edge represents
a reaction between two compounds.
10. Dense Graphs: A graph with many edges compared to the number of vertices. Example: A social
network graph where each vertex represents a person and each edge represents a friendship.
Types of Graphs:
1. Finite Graphs
A graph is said to be finite if it has a finite number of vertices and a finite number of edges. A finite graph
is a graph with a finite number of vertices and edges.
Finite graphs are often used to model real-world situations, where there is a limited number of objects and
relationships between them
2. Infinite Graph:
A graph is said to be infinite if it has an infinite number of vertices as well as an infinite number of edges.
3. Trivial Graph:
A graph is said to be trivial if a finite graph contains only one vertex and no edge. A trivial graph is a graph
with only one vertex and no edges.
4. Simple Graph:
A simple graph is a graph that does not contain more than one edge between the pair of vertices. A simple
railway track connecting different cities is an example of a simple graph.
5. Multi Graph:
Any graph which contains some parallel edges but doesn’t contain any self-loop is called a multigraph. For
example a Road Map.
• Parallel Edges: If two vertices are connected with more than one edge then such edges are called
parallel edges that are many routes but one destination.
• Loop: An edge of a graph that starts from a vertex and ends at the same vertex is called a loop or a self-
loop.
6. Null Graph:
A graph of order n and size zero is a graph where there are only isolated vertices with no edges connecting
any pair of vertices. A null graph is a graph with no edges. In other words, it is a graph with only vertices
and no connections between them. A null graph can also be referred to as an edgeless graph, an isolated
graph, or a discrete graph
7. Complete Graph:
A simple graph with n vertices is called a complete graph if the degree of each vertex is n-1, that is, one
vertex is attached with n-1 edges or the rest of the vertices in the graph. A complete graph is also called
Full Graph
8. Pseudo Graph:
A graph G with a self-loop and some multiple edges is called a pseudo graph. A pseudograph is a type of
graph that allows for the existence of loops (edges that connect a vertex to itself) and multiple edges
(more than one edge connecting two vertices). In contrast, a simple graph is a graph that does not allow
for loops or multiple edges.
4. Advantages of graphs
1. Graphs can be used to model and analyze complex systems and relationships.
2. They are useful for visualizing and understanding data.
3. Graph algorithms are widely used in computer science and other fields, such as social network analysis,
logistics, and transportation.
4. Graphs can be used to represent a wide range of data types, including social networks, road networks, and
the internet.
5. Application of Graphs
Graph :
A graph is a collection of two sets V and E where V is a finite non-empty set of vertices and E is a finite non-
empty set of edges.
• Vertices are nothing but the nodes in the graph.
• Two adjacent vertices are joined by edges.
• Any graph is denoted as G = {V, E}.
A graph is a collection of vertices (also known as nodes) and edges that connect these vertices. Each edge
represents a relationship or connection between two vertices.
Graphs can be directed or undirected, meaning that edges have a specific direction or they do not.
Tree :
A tree is a special type of graph that is connected and acyclic, meaning that there are no cycles in the graph.
In a tree, there is a unique path between any two vertices, and there is a single vertex called the root that is
used as the starting point for traversing the tree.
Trees can be used to model hierarchical relationships, such as the structure of a file system or the organization
of a company.
Binary trees can be used to solve problems such as searching and sorting, as well as to represent expressions
and parse trees.
Graph vs Tree
The basis of
Comparison Graph Tree
Graph Tree
A graph can be connected or disconnected, A tree is a type of graph that is
can have cycles or loops, and does not connected, acyclic (meaning it has no
necessarily have a root node. cycles or loops), and has a single root
node.
Structure cycle
Each node can have any number of edges. If there is n nodes then there would be n-
1 number of edges
Edges
Types of Edges They can be directed or undirected They are always directed
Graph Tree
nodes. root node, which has no parent.
The Breadth First Search (BFS) algorithm is used to search a graph data structure for a node that meets a
set of criteria. It starts at the root of the graph and visits all nodes at the current depth level before moving
on to the nodes at the next depth level.
Step 4: Remove node 1 from the front of queue and visit the unvisited neighbours and
push them into queue.
Step 5: Remove node 2 from the front of queue and visit the unvisited neighbours and
push them into queue.
Step 6: Remove node 3 from the front of queue and visit the unvisited neighbours and
push them into queue.
As we can see that every neighbours of node 3 is visited, so move to the next node that
are in the front of the queue.
Steps 7: Remove node 4 from the front of queue and visit the unvisited neighbours
and push them into queue.
As we can see that every neighbours of node 4 are visited, so move to the next node
that is in the front of the queue.
2.3.3. Table in data structure
Table is a data structure which plays a significant role in information retrieval. A set of n distinct records
with keys K1, K2, …., Kn are stored in a file. If we want to find a record with a given key value, K,
simply access the index given by its key k.
A Hash table is defined as a data structure used to insert, look up, and remove keyvalue pairs quickly. It
operates on the hashing concept, where each key is translated by a hash function into a distinct index in an
array. The index functions as a storage location for the matching value. In simple words, it maps the keys
with the value.
Hash Table is a data structure which store data in associative manner. In hash table, data is stored in array
format where each data value has its own unique index value. Access of data becomes very fast if we
know the index of desired data.
Hash table: The memory area where the keys are stored is called hash table.
It becomes a data structure in which insertion and search operations are very fast irrespective of size of
data. Hash Table uses array as a storage medium and uses hash technique to generate index where an
element is to be inserted or to be located from.
Hashing is a technique to convert a range of key values into a range of indexes of an array. We're going to
use modulo operator to get a range of key values. Consider an example of hashtable of size 20, and
following items are to be stored. Item are in (key, value) format.
A Function that translates keys to array indices is known as a hash function. The keys should be evenly
distributed across the array via a decent hash function to reduce collisions and ensure quick lookup
speeds.
• Integer universe assumption: The keys are assumed to be integers within a certain range according to
the integer universe assumption. This enables the use of basic hashing operations like division or
multiplication hashing.
• Hashing by division: This straightforward hashing technique uses the key’s remaining value after
dividing it by the array’s size as the index. When an array size is a prime number and the keys are
evenly spaced out, it performs well.
• Hashing by multiplication: This straightforward hashing operation multiplies the key by a constant
between 0 and 1 before taking the fractional portion of the outcome. After that, the index is
determined by multiplying the fractional component by the array’s size. Also, it functions effectively
when the keys are scattered equally.
Selecting a decent hash function is based on the properties of the keys and the intended functionality of
the hash table. Using a function that evenly distributes the keys and reduces collisions is crucial.
• To ensure that the number of collisions is kept to a minimum, a good hash function should distribute
the keys throughout the hash table in a uniform manner. This implies that for all pairings of keys, the
likelihood of two keys hashing to the same position in the table should be rather constant.
• To enable speedy hashing and key retrieval, the hash function should be computationally efficient.
• It ought to be challenging to deduce the key from its hash value. As a result, attempts to guess the key
using the hash value are less likely to succeed.
• A hash function should be flexible enough to adjust as the data being hashed changes. For instance,
the hash function needs to continue to perform properly if the keys being hashed change in size or
format.
Collisions happen when two or more keys point to the same array index. Chaining, open addressing, and
double hashing are a few techniques for resolving collisions.
Here, if there is a collision we have to save data as linked list
Here, if collision occurs we save data in next free space
Here, f(i)=i2
Exercises