CSC 231-Data Structure and Algorithms
CSC 231-Data Structure and Algorithms
Logical Operators: These are used to perform logical operations or comparison of two or
more operands to result to Boolean values (true or false). Table 3 below shows the logical
operators in Visual Basic.
Table 3: Logical operators
Operators Description Examples (A = True or 1, B
= False or 0)
AND It will return true if both operands are non-zero A AND A = True, A AND B
(1) = False
OR It will return true if any one operand become a A OR B = True, B Or B =
non-zero False
NOT It will return the reverse of a logical state of that
means if both operand are non-zero, it will
return false.
Relational Operators: These are used for comparisons among operands or variables and
other types of information in a program. The values return are either true or false. The
relations or comparison operators are shown in Table 4 below
Table 4: Relational operators
Operators Description Examples (a = 10,
b = 5)
< It returns true if the right operand is greater than the left a < b = False
operand
<= It will return true if the right operand is greater than or equal a <= b = False
to the left operand.
> It will return true if the left operand is greater than the right a > b = True
operand.
>= It will return true if the left operand is greater than or equal a >= b = True
to the right operand.
= It will return true if both operands are equal. a = b = False
<> It will return true if both operands are not equal. a <> b = True
Is It will return true if two object references refer to the same
object.
IsNot It will return true if two object references refer to different
objects.
Assignment Operators: This is used to assign new values to operands. Typical assignment
operators and examples are shown in Table 5 below.
Table 5: List of Assignment operators
Operators Descriptions Examples
= It will assign a value to a variable or property. a = 10
+= It will add left and right operands and assign a result a += 10 equals to a = a +
to the left operand. 10
-= It will subtract left and right operands and assign a a -= 10 equals to a = a - 10
result to the left operand.
*= It will multiply left and right operands and assign a a *= 10 equals to a = a *
result to the left operand. 10
/= It will divide left and right operands and assign the a /= 10 equals to a = a / 10
floating-point result to the left operand.
\= It will divide left and right operands and assign the a \= 10 equals to a = a \ 10
integer result to the left operand.
^= It will raise the value of a variable to the power of a ^= 10 equals to a = a ^ 10
expression and assign the result back to the variable.
++ Increment operators that increase the value of a++ equal to a = a +1, 10 +
operand by 1 1 = 11
-- Decrement operator that decrease the value of a-- equal to a = a -1, 10 - 1
operand by 1 =9
Concatenation Operators: Concatenation operators are useful to concatenate or join
defined operators based on requirements. Examples of concatenation operators are shown
in the table 6 below.
Table 6: Concatenation operators in Visual Basic
Operators Descriptions Examples (a = “Hello”, b =
“world”
& It will concatenate given two expression a & b = “Helloworld”
+ It is useful to add two numbers or concatenate two a + b = “Helloworld”
string expression
3. (𝑞 − 𝑥)2
𝑎+𝑏 𝑒−𝑓
4. 𝑐−𝑑
÷ 𝑔+ℎ
5. (𝑎 + 𝑏 + 𝑐)/2
𝜋 𝑈𝑎𝑣
6. ( 100 )
4
−𝑏±√𝑏 2 −4𝑎𝑐
7. 2𝑎
1. Primitive data structure: Primitive data structure is a data structure that can hold a single
value in a specific location whereas the non-linear data structure can hold multiple values
either in a contiguous location or random locations.
2. Non-primitive data structure: The non-primitive data structure is a kind of data structure
that can hold multiple values either in a contiguous or random location. The non-primitive
data types are defined by the programmer. The non-primitive data structure is further
classified into two categories, i.e., linear and non-linear data structure.
3.7 Differences between primitive data structure and non-primitive data structure
Table 8: difference between primitive and non-primitive data structure
Primitive Data structure Non-primitive data structure
Primitive data structure is a kind of data structure that Non-primitive data structure is a type of data structure
stores the data of only one type. that can store the data of more than one type.
Examples of primitive data structure are integer, Examples of non-primitive data structure are Array,
character, and float. Linked list, stack.
Primitive data structure will contain some value, i.e., it Non-primitive data structure can consist of a NULL
cannot be NULL. value.
The size depends on the type of the data structure. In case of non-primitive data structure, size is not fixed.
It starts with a lowercase character. It starts with an uppercase character.
Primitive data structure can be used to call the methods. Non-primitive data structure cannot be used to call the
methods.
Integer: The integer data type contains the numeric values. It contains the whole numbers
that can be either negative or positive. When the range of integer data type is not large
enough then in that case, we can use long.
Float: The float is a data type that can hold decimal values. When the precision of decimal
value increases then the Double data type is used.
Boolean: It is a data type that can hold either a True or a False value. It is mainly used for
checking the condition.
Character: It is a data type that can hold a single character value both uppercase and
lowercase such as 'A' or 'a'.
a. Linear: elements are stored and accessed linearly in computer memory, and the elements
are connected to the previous and the next element. The element can be traversed and
accessed in single run. It is easier to implement linear data structure as the element are
organized sequentially in memory. Examples are array, list, stack, string and queue.
Array: An array consists of data elements of a 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 form the list is known
as pop operation.
Queue: It is a data structure that uses the FIFO rule (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 end and rear. The insertion operation performed at the back end is
known as 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, i.e., data
element and reference to the next node in the sequence.
String: String is defined as an array of characters. The difference between the
character array and string is that the string data structure terminates with a 'NULL'
character, and it is denoted as a '\0'.
b. Non-linear: data elements are not store and accessed in sequence. Examples of nonlinear
data structure are Tree and graph.
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.
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.
1. Static linear data structure: In Static data structure the size of the structure is fixed. The
content of the data structure can be modified but without changing the memory space
allocated to it. Static data structure provides easier access to data elements. Example of
static data structure is the array. Figure 3 shows static data structure process
Figure 5: Arrays
B. Advantages of Array data structure
A convenient way to store large amounts of similar data.
It is used to represent multiple items of similar nature using a single name.
It allows us to store data in multi-dimensional arrays
It is used to create other data structures like heaps, linked lists, etc.
You need not access elements sequentially, random access is allowed.
Since elements are stored in consecutive blocks hence they are useful to use in iterations.
Since the size of the array is known during compile-time, there is no chance of memory
runout for arrays.
C. Disadvantages of array data structure
Difficult to modify the array size during program execution due to its fixed size
Inserting and deleting elements from an array is tedious as it involves shifting data
elements of the array and memory management
No element can be appended at the end of array
Lead to memory wastage as array is declared during compile time
Insertion and deletion operations are time-consuming
D. Application of Array data structure
Implementation of other data structure such as linked lists etc.
Uses in lockup table in program application
Use to implement database record
It effectively executes memory addressing logic wherein indices act as addresses to the
one-dimensional array of memory
Used in mathematical problem such as matrices, indices etc.
4.1.2 Linked List
It is a collection of data links called nodes where each node contains a data value and the address
of the next link. All elements of the linked list are not stored in neighboring memory locations. In
simple words, it is a sequence of data nodes that connect through links. Each node of a list is
consists of two items: the basic idea behind the uses of a linked list in a data structure is that each
node within the structure includes a data part where we store values, and a pointer indicates the
next node can be found. The linked list's starting point denotes the head of the list, and the
endpoints represent the node's tail.
Also, list is a sequence of zero or more elements called nodes, each containing two kind of
information-some data and one or more links to a pointer to the node of the link list. The nodes are
connected in sequence to for a linear list. The last node in the list is called tail node, and it is
indicated by a null link reference. In addition, the first node in the list must be named or referenced
by an external variable as it provide the entry point into the linked list. The variable is commonly
called the head point or head reference. A linked list can be empty which is indicated when the
head reference is null. Figure 6 provides an example of a linked list consisting of four nodes.
A. Application of Linked List
Implementation of image viewer where previous and next image are linked
Enable access of previous and next web browser by pressing back or next button since
they are linked as linked list
In music player to access next and previous song in play list
Implementation of stacks and queues
Implementation of graphs
Dynamic memory allocation: We use linked list of free memory blocks.
Maintaining directory of names
Performing arithmetic operations on long integers
Manipulation of polynomials by storing constants in the node of linked list representing
sparse matrices.
Figure 6: Linked List
4.1.3 Stack
It is a linear data structure that enables the elements to be inserted and deleted from one end, called
the Top of Stack (TOS). A stack data structure follows the last in first out (LIFO) operation to
insert and remove an element from the stack list. It is an abstract data type with two possible
operations to insert and delete elements in the stack: push and pop. A push operation is used in the
stack to insert elements at the top of the list, hide those elements that already available in the list,
or initialize the stack if it is empty. The pop operation is used in the stack data structure to delete
a data item from the top of the list. Adding and removing items in a stack is restricted to one end
of the stack called the top of the stack. An empty stack is the one containing no items.
Common stack operations are:
Stack(): Create empty stack
Push(): insert element at the top of the stack list
Pop(): delete data element form the top of the list
Peek (): Return a reference to the item on top of a non-empty stack without removing it.
Peek, which cannot be done on empty stack does not modify the stack contents.
isFull(): check if stack is full
isEmpty(): return a Boolean value indicating if the stack is empty.
Length():Return the number of items in the stack
A. Applications of stack
Reversing words
Checking parenthesis matching in expression
Expression evaluation
Conversion from one form of expression to another
Memory management
Backtracking problem
Figure 7: Stack data structure
(https://guides.codepath.com/compsci/Stacks-and-Queues)
4.1.4 Queue
It is a linear data structure that enables the insertion at one end of the list, known as the rear, and
the deletion of the elements occurred at another end of the list, called the front. It is a sequential
collection of data elements based on the First in First out (FIFO) data structure, which means the
first inserted elements in a queue will be removed first from the queue list. Queue is suited for a
problem in computer science that require data to be processed in order in which it was received.
Examples are in computer simulation, CPU process scheduling, and shared printer management.
In queue data structure, new items are inserted at the back and existing items are removed from
the front. Items are maintained in the order in which they are added to the structure.
Important queue functions are described below:
Queue(): create new empty queue, that is, queue containing no item.
Enqueue(): It is a queue operation used to insert an element to the queue.
Dequeue(): It is a queue operation used to delete an item from the queue.
Length(): returns the length of items currently in the queue
IsEmpty(): return a Boolean value indicating whether the queue is empty.
Example code snippets below show examples for creating and adding items to a given queue.
Q = Queue()
Q.enqueue(20)
Q.enqueue(19)
Q.enqueue(45)
Q.enqueue(13)
Q.enqueue(9)
B. Graph operations
Following are basic primary operations of a Graph −
Add Vertex: Adds a vertex to the graph.
Add Edge: Adds an edge between the two vertices of the graph.
Display Vertex: Displays a vertex of the graph.
Find the path from one vertex to another vertex
C. Types of Graph
a. Directed Graph: In a directed graph, nodes are connected by directed edges – they only go
in one direction. For example, if an edge connects node 1 and 2, but the arrow head points
towards 2, we can only traverse from node 1 to node 2 – not in the opposite direction.
Figure 12: directed graph
b. Undirected Graph: In an undirected graph, nodes are connected by edges that are all
bidirectional. For example if an edge connects node 1 and 2, we can traverse from node 1
to node 2, and from node 2 to 1.
Solution:
Step 1: Start
Step 2: Get the knowledge of input.
Here we need 3 variables a and b will be the user input and c will hold result.
Step 3: Declare a, b, c variables.
Step 4: Take input for a and b variable from the user.
Step 5: Know the problem and find the solution using operators’ data structures and logic. We
need to multiply a and b variables so we use * operator and assign result to c.
That is c <- a * b
Step 6: Check how to give output
Here we need to print the output. So write print c
Step 7: End
Example 2: Write an algorithm to find the maximum of all the elements present in the
array.
Solution:
Step 1: Start
Step 2: Declare a variable max with value of first element of array.
Step 3: Compare the max with other elements using loop.
Step 4: If max < array element value change max to new max.
Step 5: If no element left return or print max otherwise go to step 3.
Step 6: End
Solution:
Step 1: Start
Step 2: Declare a variable sum with value 0.
Step 3: Get sum of all the values in sum variable using loop.
Step 4: Divide sum by 6 and assign it to avg variable.
Step 5: Print avg
Step 6: End
Sorting algorithms are computer science algorithms used to rearrange element in a list in order.
The arrangement is done according to a comparison operator on the elements which decide the
new order of the element in the respective data structure. In computer science, we have different
sorting algorithms used to arrange items in ascending or descending order. Some the sorting
algorithms include bubble sort, insertion sort, merge sort, quick sort, selection sort and shell sort.
Enumeration sorting: consider all items. If we know that there are N items which are
smaller than the one we are currently considering, then its final position will be at number
N+1.
Exchange sorting: if two items are found to be out of order, exchange them. Repeat till all
items are in order
Selection sorting: find the smallest item, put it in the first position, find the smallest of the
remaining items, and put it in the second position. This process is repeated until the whole
item is sorted.
Divide and conquer: recursively split the number problem into smaller sub-problems till
you just have single items that are trivial to sort. Then, put the sorted part back together in
a way that preserve the sorting.
All the strategies are based on comparing items and then rearranging them accordingly. These are
known as comparison-based sorting algorithms. The sorting approach is based on the assumption
that the items to be sorted can fit into computer memory, and they are referred to as internal sorting
algorithms.
A. Bubble sort
Bubble sort is a simplest sorting algorithm. The sorting algorithm is comparison-based algorithm
in which each pair of adjacent item elements is compared with the next element and the elements
are then swapped if they are out of order. Using this approach, bubble algorithms makes (n-1)
passes to completely sort set of items. During the first pass, R1 and R2 are compared, and if R1 is
greater than R2, then R1 and R2 are interchanged. The process is repeated for R2, R3, R4 etc., in
the same passes. The procedure will cause elements with smaller values to move up (bubble up)
after the first pass, and the element with the largest value will be in the nth position (last position).
Therefore, on the subsequent passes, the element with the next largest values will be placed in the
position (n-1), (n-2), (n-3),… 4, 3, 2, respectively, thereby resulting in sorted list. After each
passes, the subsequent passes will be performed on the first (n-ith passes) elements in the list since
all the elements, starting from the last position, up to the (n-i) position have taken their appropriate
positions.
After each pass through the list, a check could be made to determine whether or not any
interchanges were made during that pass. If no interchange was made, then the list must have been
sorted at that point and no further passes are required. Otherwise, we loop onto the next pass.
The algorithm for bubble sorting is given below.
1. Loop on the pass index, and repeat the steps 2 and 3 for j = 1, 2, 3, ….., n-1
2. Initialize interchange indicator and set CHECK = 0
3. Make passes
a. Repeat steps for j = 1, 2, 3, …, n-1
b. If Rj+1< Rj, then interchange Rj with Rj+1 and set CHECK = 1
c. If CHECK = 0, then sorting is done.
4. Sorting completed, and stop.
5. Print sorted list.
Bubble sort is the simplest sorting algorithm, however, it is not suitable for large dataset as its
average and worst case complexity are of Ο(n2) where n is the number of items.
The procedure is further illustrated in Table 2 below
Table 9: bubble sort procedure
Pass Number
j Rj 1 2 3 4 5 6 Sorted
1 40 21 21 9 9 9 9
2 21 40 9 21 21 21 21
3 72 9 40 40 40 34 34
4 9 63 56 56 34 40 40
5 63 56 63 34 56 56 56
6 56 72 34 63 63 63 63
7 92 85 72 72 72 72 72
8 34 92 85 85 85 85 85
9 97 85 92 92 92 92 92
10 85 97 97 97 97 97 97
5.10 Searching algorithm
Searching is the process of examining a set of items to find out those that have desired property.
Searching algorithms helps to find required information from a collection of items stored as
element in the computer memory. These set of items are in different forms such as array, linked
list, graph or tree. Therefore, desired items are located using specific characteristics in a collection
of items. Searching in data structure can be done by applying searching algorithms to check for or
extract an element from any form of stored data structure. Search algorithms are classified based
on operation they perform. Typical classification include:
Sequential search: the list of array of elements is traversed sequentially while checking
every component of the set. Typical example is the linear search algorithm.
Interval search: these include algorithms that are explicitly designed for searching in sorted
data structure. In terms of efficiency, these algorithms are better than linear search
algorithms. Examples are logarithm search and binary search.
Search algorithms are evaluated based on the time taken to search for an element matching the
search item in the data collection and given by best possible time, average time and worst-case
time. There are many searching algorithms in data structure, some these algorithms include linear
search, binary search, interpolation search, sublist search, exponential search, Fibonacci search
etc.
In this subsection, linear search algorithm, a representative searching algorithm is discussed.
5.10.1 Linear search
Linear search algorithm iteratively searches all elements in array. it is a simple algorithm that
check every items in the list sequentially to locate the desired element. The algorithm of linear
search is given below:
Linear Search ( Array A, Value x)
Step 1: Set i to 1
Step 2: if i > n then go to step 7
Step 3: if A[i] = x then go to step 6
Step 4: Set i to i + 1
Step 5: Go to Step 2
Step 6: Print Element x Found at index i and go to step 8
Step 7: Print element not found
Step 8: Exit
end procedure
Algorithm analysis is process of providing theoretical estimates for the resources needed by any
algorithm which solves a given computational problem. This estimates provide insight into
reasonable directions of search for efficient algorithms. Algorithm analysis provide common
estimate for their complexity function for arbitrary input which is measured by Big O notation,
Big-omega notation, and Big-theta notation. Algorithm of analysis is an important part of
computational complexity theory. Usually, the efficiency or running time of an algorithm is stated
as a function relating the input length to the number of steps known as time complexity, or volume
of memory know as space complexity.