ADSA-total - Lecture notes 1 PDF

Title ADSA-total - Lecture notes 1
Author swathi
Course Advanced Data Structure and Algorithms
Institution Jawaharlal Nehru Technological University Anantapur
Pages 224
File Size 11.5 MB
File Type PDF
Total Downloads 95
Total Views 132

Summary

total Advanced data structures and algorithms...


Description

UNIT- I Overview of Data Structures - Arrays, Stacks, Queues, linked lists , Linked stacks and Linked queues, Applications Algorithm Analysis - Efficiency of algorithms, Asymptotic Notations, Time complexity of an algorithm using O notation, Polynomial Vs Exponential Algorithms, Average, Best, and Worst Case Complexities, Analyzing Recursive Programs. Overview of Data Structures I

In simple language,

Basic types of Data Structures .

   

All these data structures allow us to perform different operations on data. We select these data structures based on which type of operation is required. We will look into these data structures in more details in our later lessons.

The data structures can also be classified on the basis of the following characteristics:

Dynamic structures are those which expands or shrinks depending upon the

What is an Algorithm ? An algorithm is a finite set of instructions or logic, written in order, to accomplish a certain lgorithm is not the complete code or program, it is just the core logic(solution)

of a problem, Every Algorithm must satisfy the following properties:

. An algorithm is said to be efficient and fast, if it takes less time to execute and consumes less memory space. The performance of an algorithm is measured on the basis of following properties: 1. Time Complexity 2. Space Complexity

Space Complexity Its the amount of memory space required by the algorithm, during the course of its execution. S An algorithm generally requires space for following components : 

space is f

Its the space required

 

: Its the space required , but varies d

E

. This in the program. .

Its the space require .

We will study this in details in later sections. Time Complexity of Algorithms Time complexity of an algorithm signifies the total time required by the program to run till its completion. . Time Complexity is most commonly performed by the algorithm. And since the algorithm's performance may vary with different types of input data, hence for an algorithm we usually use th

Calculating Time Complexity Now lets tap onto the next big topic related to Time complexity, which is How to Calculate Time Complexity. It becomes very confusing some times, but we will try to explain it in the simplest way. Now the most common metric for calculating time complexity is Big O notation. This removes all constant factors so that the running time can be estimated in relation to N, as N approaches infinity. In general you can think of it like this :

Above we have a single statement. Its Time Complexity will be Co t

. The running time of

The time complexity for the above algorithm will be L The running time of the loop is directly proportional to N. When N doubles, so does the running time.

} This time, the time complexity for the above code will be The running time of the two loops is proportional to the square of N. When N doubles, the running time increases by N * N.

} This is an algorithm to break a set of numbers into halves, to search a particular field(we will study this in detail later). Now, this algorithm will hav . The running time of the algorithm is proportional to the number of times N can be divided by 2(N is high-low here). This is because the algorithm divides the working area in half with each iteration. void quicksort(int list[], int left, int right) { int pivot = partition(list, left, right); quicksort(list, left, pivot - 1); quicksort(list, pivot + 1, right); } Taking the previous algorithm forward, above we have a small logic of Quick Sort(we will study this in detail later). Now in Quick Sort, we divide the list into halves every time, but we repeat the iteration N times(where N is the size of list). Hence time complexity will be N*log( N ). The running time consists of N loops (iterative or recursive) that are logarithmic, thus the algorithm is a combination of linear and logarithmic. NOTE : In general, doing something with every item in one dimension is linear, doing something with every item in two dimensions is quadratic, and dividing the working area in half is logarithmic.

Types of Notations for Time Complexity Now we will discuss and understand the various notations used for Time Complexity. 1 . .

…………………………………………………………………………………………………...

Whenever we want to work with large number of data values, we need to use that much number

An array can also be defined as follows...

To understand the concept of arrays, consider the following example declaration. i Here, the compiler allocates 2 bytes of memory with name 'a', another 2 bytes of memory with name 'b' and more 2 bytes with name 'c'. These three memory locations are may be in sequence or may not be in sequence. Here these individual variables can store only one value at a time.

Now consider the following declaration... i Here, the compiler allocates total 6 bytes of continuous memory locations with single name 'a'. But allows to store three different integer values (each in 2 bytes of memory) at a time. And memory is organized as follows...

That means all these three memory locations are named as 'a'. But "how can we refer individual elements?" is the big question. Answer for this question is, compiler not only allocates memory,

but als

. Index values for the above example are as follows...

The individual elements of an array are identified using the combination of 'name' and 'index' as follows...

For the above example the individual elements can be referred to as follows...

If I want to assign a value to any of these memory locations (array elements), we can assign as follows... ; The result will be as follows...

x

What is Sparse Matrix? I There may be a situation in which Such matrix is known as sparse matrix.

When a sparse matrix is represented with 2-dimensional array, nt tha . For example, consider a matrix of size 100 X 100 containing only 10 non-zero elements. In this matrix, only 10 spaces are filled with non-zero values and remaining spaces of matrix are filled with zero. That means, totally we allocate 100 X 100 X 2 = 20000 bytes of space to store this integer matrix. And to access these 10 non-zero elements we have to make scanning for 10000 times.

. c can be represented as shown in the image...

his matrix

In above example matrix, there are only 6 non-zero elements ( those are 9, 8, 4, 2, 5 & 2) and matrix size is 5 X 6. We represent this matrix as shown in the above image. Here the first row in the right side table is filled with values 5, 6 & 6 which indicates that it is a sparse matrix with 5 rows, 6 columns & 6 non-zero values. Second row is filled with 0, 4, & 9 which indicates the value in the matrix at 0th row, 4th column is 9. In the same way the remaining non-zero values also follows the similar pattern.

Consider the above same sparse matrix used in the Triplet representation. This sparse matrix can be represented using linked representation as shown in the below image...

In above representation, H0, H1,...,H5 indicates the header nodes which are used to represent indexes. Remaining nodes are used to represent non-zero elements in the matrix, except the very first node which is used to represent abstract information of the sparse matrix (i.e., It is a matrix of 5 X 6 with 6 non-zero elements). In this representation, in each row and column, the last node right field points to it's respective header node.

In a stack, the insertion operation is performed using a function called "push" and deletion operation is performed using a function called "pop". In the figure, PUSH and POP operations are performed at top position in the stack. That means, both the insertion and deletion operations are performed at one end (i.e., at Top) A stack data structure can be defined as follows...

Stack can also be defined as

Example If we want to create a stack by inserting 10,45,12,16,35 and 50. Then 10 becomes the bottom most element and 50 is the top most element. Top is at 50 as shown in the image below...

The following operations are performed on the stack... 1. Push (To insert an element on to the stack) 2. Pop (To delete an element from the stack) 3. Display (To display elements of the stack) Stack data structure can be implement in two ways. They are as follows... 1. Using Array 2. Using Linked List When stack is implemented using array, that stack can organize only limited number of elements. When stack is implemented using linked list, that stack can organize unlimited number of elements. Stack Using Array A stack data structure can be implemented using one dimensional array. But stack implemented using array, can store only fixed number of data values. This implementation is very simple, just define a one dimensional array of specific size and insert or delete the values into that array by using LIFO principle with the help of a variable 'top'. Initially top is set to -1. Whenever we want to insert a value into the stack, increment the top value by one and then insert. Whenever we want to delete a value from the stack, then delete the top value and decrement the top value by one. A stack can be implemented using array as follows... 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'. (int 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.

push(value) - Inserting value into the stack In a stack, push() is a function used to insert an element into the stack. In a stack, the new element is always inserted at topposition. Push function takes one integer value as parameter and inserts that value into the stack. We can use the following steps to push an element on to the stack... 

Step 1: Check whether stack is FULL. (top == SIZE-1)



Step 2: If it is FULL, then display "Stack is FULL!!! Insertion is not possible!!!" and terminate the function.



Step 3: If it is NOT FULL, then increment top value by one (top++) and set stack[top] to value (stack[top] = value).

pop() - Delete a value from the Stack In a stack, pop() is a function used to delete an element from the stack. In a stack, the element is always deleted from topposition. Pop function does not take any value as parameter. We can use the following steps to pop an element from the stack... 

Step 1: Check whether stack is EMPTY. (top == -1)



Step 2: If it is EMPTY, then display "Stack is EMPTY!!! Deletion is not possible!!!" and terminate the function.



Step 3: If it is NOT EMPTY, then delete stack[top] and decrement top value by one (top--).

display() - Displays the elements of a Stack We can use the following steps to display the elements of a stack... 

Step 1: Check whether stack is EMPTY. (top == -1)



Step 2: If it is EMPTY, then display "Stack is EMPTY!!!" and terminate the function.



Step 3: If it is NOT EMPTY, then define a variable 'i' and initialize with top. Display stack[i] value and decrement i value by one (i--).



Step 3: Repeat above step until i value becomes '0'.

he as '

the in n operation is performed at a position which is known ' and the deletion operation is performed at a position which is known as ' '. In queue

data structure, the insertion and deletion operations are performed based on

In a queue data structure, the insertion operation is performed using a function called "enQueue()" and deletion operation is performed using a function called "deQueue()". Queue data structure can be defined as follows...

A queue can also be defined as "

Example Queue after inserting 25, 30, 51, 60 and 85.

Operations on a Queue The following operations are performed on a queue data structure... 1. enQueue(value) - (To insert an element into the queue) 2. deQueue() - (To delete an element from the queue) 3. display() - (To display the elements of the queue) Queue data structure can be implemented in two ways. They are as follows... 1. Using Array

2. Using Linked List When a queue is implemented using array, that queue can organize only limited number of elements. When a queue is implemented using linked list, that queue can organize unlimited number of elements.

. Simply a list is a sequence of data, and linked list is a sequence of data linked with each other. The formal definition of a single linked list is as follows... S

In an used

to

store

the

data field is used to store actual value of that node and next field is address of the next node in the sequence.

The graphical representation of a node in a single linked list is as follows...

NOTE: ☀I as "front" (Some times it is also known as " ☀ Al Example

a reference node known .

In a single linked list we perform the following operations... 1. Insertion 2. Deletion 3. Display Before we implement actual operations, first we need to setup empty list. First perform the following steps before implementing actual operations. 

Step 1: Include all the header files which are used in the program.



Step 2: Declare all the user defined functions.



Step 3: Define a Node structure with two members data and next



Step 4: Define a Node pointer 'head' and set it to NULL.



Step 4: Implement the main method by displaying operations menu and make suitable function calls in the main method to perform user selected operation.

e list We can use the following steps to insert a new node at beginning of 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, set newNode→next = head and head = newNode.

Inserting At End of the list We can use the following steps to insert a new node at end of the single linked list... 

Step 1: Create a newNode with given value and newNode → next as NULL.



Step 2: Check whether list is Empty (head == NULL).



Step 3: If it is Empty then, set 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 last node in the list (until temp → next is equal to NULL).



Step 6: Set temp → next = newNode.

Inserting At Specific location in the list (After a Node) 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'

Deleting from Beginning of the list We can use the following steps to delete a node from beginning of the 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 a Node pointer 'temp' and initialize with head.



Step 4: Check whether list is having only one node (temp → next == NULL)



Step 5: If it is TRUE then set head = NULL and delete temp (Setting Empty list conditions)



Step 6: If it is FALSE then set head = temp → next, and delete temp.

Deleting from End of the list We can use the following steps to delete a node from end of the 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: Check whether list has only one Node (temp1 → next == NULL)



Step 5: If it is TRUE. Then, set head = NULL and delete temp1. And terminate the function. (Setting Empty list condition)



Step 6: If it is FALSE. Then, set 'temp2 = temp1 ' and move temp1 to its next node. Repeat the same until it reaches to the last node in the list. (until temp1 → next == NULL)



Step 7: Finally, Set temp2 → next = NULL and delete temp1.

Deleting a Specific Node from the list We can use the following steps to delete a specific node from the 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.

<...


Similar Free PDFs