Class Notes
Class Notes
Class Notes
Q. What is computer?
- Computer is a machine/hardware/digital device can be used to perform different tasks
efficiently and effectively.
- basic functions of computer:
1. data storage
2. data processing
3. data movement
4. control
2. "non-linear/advanced data structures": data ele's gets stored into the memory in a non-linear
manner and hence can be accessed in a non-linear manner.
- tree (heirachical)
- graph (network)
- hash table (associative i.e. key-value pairs)
- binary heap
etc...
+ "array": it is a collection/list of logically related similar type of elements which gets stored into
the memory in a contiguos manner.
+ "structure": it is a collection of logically related similar and disimilar type of
elements, gets stored into the memory collectively.
+ "union":
Algorithm ArraySum(A, n)
{
sum=0;
for( index = 1 ; index <= n ; index++ )
sum += A[index];
return sum;
}
//program- function
int ArraySum(int *arr, int size)
{
int sum=0;
int index;
return sum;
}
- One problem may has many solutions, when one problem has many solutions we need to select an
efficient solution/algo.
- to decide an efficiency of an algo's we need to do their analysis.
- analysis of an algo: it is a work of calculating how much "time" i.e. computer time
and "space" i.e. computer memory it needs to run to completion.
- there are two measures of an analysis of an algo:
1. time complexity
2. space complexity
1. "time complexity": time complexity of an algo is the amount of "time" i.e. computer time it needs
to run to completion.
2. "space complexity": space complexity of an algo is the amount of "space" i.e. computer memory
it needs to run to completion.
-------------------------------------------------------------------------------------
# Array Operations:
1. Linear Search:
- in this algo, we start comparing key ele with first ele in a collection/list of ele's and we compare
key ele with each ele in a collection/list ele's sequentially either till match is found or maximum till
the last ele.
return false;
}
- In Linear Search:
* "best case": occures if key is found at very first position, in this case only 1 comparison takes
place --> running time of an algo in this case = O(1).
best case : Big Omega(1)
* "worst case": occures either if key is found at last position or key does not exists, in this case "n"
no. comparison takes place, wheras n is size of an array
--> running time of an algo in this case = O(n).
worst case: Big Oh(n)
Asymptotic Notations:
1. Big Oh( O ): this notation can be used to represent worst case time complexity of an algo.
2. Big Omega( ): this notation can be used to represent best case time complexity of an algo
3. Big Theta ( ): this notation can be used to represent an average case time time complexity of an
algo.
2. Binary Search:
- this algo follows "divide-and-conquer" statergy
- if we want to apply binary search on array, prerequisite is that
array ele's must be in sorted manner
return false;
}
- In Binary Search:
* "best case": occures if key is found at mid pos in very first iteration, in this case only 1
comparison takes place --> running time of an algo in this case = O(1).
best case : Big Omega(1)
- while comparing two algo's, we always decides effieciency of an algo depends on worst case time
complexity.
worst case time complexity of linear search = O(n)
worst case time complexity of binary search = O(log n)
1. selection sort:
- in this algo, in the first iteration first position gets selected and ele which is at selected position
gets compared with remaining all positions ele's, if we found any ele smaller than element which is
at selected pos then we will swap them with it, so in first iteration the smallest ele gets
setteled/fixed at first position
in second iteration, second position gets selected, and gets compared with remaining all its next
positions ele's, if we found any ele smaller than element which is at selected pos then we will swap
them with it, so in second iteration second smallest ele gets settled/fixed at second position, and so
on.... in max (n-1) no. of iterations all array ele's gets arranged in a sorted manner.
Algorithm SelectionSort(A, n)
{
for( sel_pos = 1 ; sel_pos <= n ; sel_pos++ )//O(n)
{
for( pos = sel_pos + 1 ; pos <= n-1 ; pos++ )//O(n*n)
{
if( A[ sel_pos ] > A[ pos ] )
SWAP(A[sel_pos], A[pos]);
}
}
}
2. Bubble Sort:
- in this algo, ele's which are at two consecutive positions gets compared with each other, if they are
in order then no need of swapping, but if they are not in order then swapping takes place between
them,
in first iteration the largest ele gets fixed/setteled at its appropriate pos i.e. at last pos, in seond
iteration next largest ele gets setteled at its appropriate pos i.e. at at second last pos and so on.... in
max (n-1) no. of iterations all array ele's gets arranged in a sorted manner.
4. Merge Sort:
- this algo follows "divide-and-conquer" stratergy
- we need to divide big size array into subarray's of smallest size
and after dividing merge all subarray's into a single array in a sorted manner.
5. Quick Sort:
- this algo follows "divide-and-conquer" stratergy
- "partitioning" is the main logic which gets applied in this algo on array
- this algo can be applied only on array data structure
1. selection sort
2. bubble sort
3. insertion sort
4. quick sort
5. merge sort
# Asymptotic Analysis:
- Asymptotic Notations:
1. Big Oh (O): this notation can be used to represent worst case time complexity
i.e. asymptotic upper bound.
2. Big Omega (): this notation can be used to represent best case time complexity
i.e. asymptotic lower bound.
3. Big Theta (): this notation can be used to represent an average case time
complexity
i.e. asymptotic tight bound.
------------------------------------------------------------------------------------
Q. What is Linked List?
It is a collection/list of logically related similar type of elements in which,
- address of first element in a list gets stored into a pointer a variable
reffered as "head", and
- each element will going contains "actual data" (is of any primitive/non
primitive type) and addr of its next (as well as prev) element in it.
2. "Doubly Linked List": in this type of linked list each node contains addr of
its next node as well as addr of its prev node.
- futher doubly linked list is divided into two types:
I. doubly linear linked list
II. doubly circular linked list
-----------------------------------------------------------------------------------
struct node
{
int data;
struct node *next;//self-referential pointer
};
- limitations of singly linked list (singly linear as well singly circular) linked list:
1. we can traverse singly linked list only in a forward direction
2. we cannot access prev node of any node from it
and hence to overcome these limitations doubly linked list has been designed.
=======================================================================
=============
# Stack: it is a collection/list of logically related similar type of ele's in which
elements can be added as well deleted from only one end reffered as "top" end.
- in this list element which was inserted last can only be deleted first, so this list works in "last in
first out" manner, hence it is also called as "LIFO" list/"FILO" list.
- we can perform three basic operations onto the stack in O(1) time:
1. Push: to insert/add an ele into the stack at top end/position
2. Pop : to remove/delete an ele from the stack which is at top end/position
3. Peek: to get the value of an element which is at top end/position.
#define SIZE 5
typedef struct
{
int arr[SIZE];
int top;
}stack_t;
arr: int [] -> non-primitive data type
top: int -> primitive data type
- we can perform three basic operations onto the stack in O(1) time:
1. Push: to insert/add an ele into the stack at top end/position:
step1: check stack is not full
step2: increment the value of top by 1
step3: insert/add ele onto the at top position/end
Push: add_last()
Pop: delete_last()
OR
Push: add_first()
Pop: deelete_first()
# what is an expression?
- an expression is a combination of an operands and operators
e.g. there are three types of expression
1. infix expression : a+b
2. prefix expression : +ab
3. postfix expression : ab+
infix expression: a*b/c*d*e+f/g-h
-------------------------------------------------
topmost ele = *
cur ele = +
prefix expression: - + * * / * a b c d e / f g h
--------------------------------------------------------------------------------------
- postfix evaluation:
postfix expression: 4 5 6 * 7 / + 8 3 * +
456*7/+83*+
stack
-------------
32
=======================================================================
==============
# queue: it is a collection/list of logically related similar type of ele's into
which ele's can be added from one end reffered as "rear" end, whereas ele's can be deleted from
another end reffered as "front" end.
- in this list ele which was inserted first can be deleted first, so this list works in "first in first out"
manner, and hence this list is also called as "FIFO"/"LILO"
list.
- we can perform two basic operations onto this queue in O(1) time:
1. enqueue: to insert/add/push an ele into the queue from rear end/position
2. dequeue: to delete/remove/pop ele from the queue which is at front position/end
2. output restricted deque: it is a type of deque in which we can insert ele's into it from both the
ends, but we can delete ele's only from one end.
1. implementation of linear queue: by using an array
#define SIZE 5
typedef struct
{
int arr[SIZE];
int front;
int rear;
}queue_t;
arr : int []
front : int
rear : int
- we can perform two basic operations onto this queue in O(1) time:
1. enqueue: to insert/add/push an ele into the queue from rear end/position:
step1: check queue is not full
step2: increment the value of rear by 1
step3: insert an ele into the queue at rear position
step4: if( front == -1 )
front = 0
- we can perform two basic operations onto this queue in O(1) time:
1. enqueue: to insert/add/push an ele into the queue from rear end/position:
step1: check queue is not full
step2: increment the value of rear by 1 [ rear = (rear+1)%SIZE ]
step3: insert an ele into the queue at rear position
step4: if( front == -1 )
front = 0
2. dequeue: to delete/remove/pop ele from the queue which is at front position/end
step1: check queue is not empty
step2: if( front == rear )//we are deleting last ele
{
front = rear = -1;
}
else
{
increment the value of front by i.e. we are deleting ele from the
queue
[front = (front+1) %SIZE ]
}
enqueue: add_last()
dequeue: delete_first()
OR
enqueue: add_first()
dequeue: delete_last()
+ applications of queue:
- queue gets used to implement os data structures like job queue, ready queue, message queue etc...
- queue is used to implement os algorithms like priority cpu sched, FIFO page replacement algo,
fcfs cpu sched etc...
- queue is used to implement advanced data structure algo's like "bfs traversal" in tree & graph.
BFS: Breadth First Search
- queue can be used in any application/system program where collection/list of ele's should work in
first in first out manner.
=======================================================================
===============
+ tree: it is a non-linear, advanced data structure which is a collection of finite no. of logically
related similar type of elements in which,
- there is first ele which is specially designated element reffered as "root" ele, and
- remaining all ele's are connected to the root ele in a heirarchical manner, follows parent-child
relationship.
- tree data structure is "dynamic" in nature, i.e. any node can have any no. of child nodes and tree
data structure can grow in a downward direction at any level.
- as in tree data structure any node can have any no. of childs and it can grow at any level,
operations like addition, deletion, searching, traversal etc... on it cannot performed efficiently,
sorestrictions can be applied on tree data structure
to achieve efficiency and hence there are different type of tree data strucure.
* "binary tree": it is a tree in which each node can have max 2 no. of child nodes
i.e. each node can have either 0 OR 1 OR 2 no. of child nodes.
binary tree is a tree in which degree of each node is either 0 OR 1 OR 2.
- binary tree: it is tree which is a set of finite no. of ele's having three subsets
1. root node
2. left subtree(may be empty)
3. right subtree(may be empty)
* "binary search tree"/BST: it is a binary tree in which left child is always smaller than its parent
and right child is always greater or equal to its parent.