Data Structures - SCSA1203: Unit - I
Data Structures - SCSA1203: Unit - I
Characteristics of an Algorithm
An algorithm must follow the mentioned below characteristics:
✱ Input: An algorithm must have 0 or well- d e f i n e d inputs.
✱ Output: An algorithm must have 1 or well-defined outputs, and should match with
the desired output.
✱ Feasibility: An algorithm must be terminated after the finite number of steps.
✱ Independent: An algorithm must have step-by-step directions which is
independent of any programming code.
✱ Unambiguous: An algorithm must be unambiguous and clear. Each of their steps
and input/outputs must be clear and lead to only one meaning.
The performance of algorithm is measured on the basis of following properties:
✱ Time complexity: It is a way of representing the amount of time needed by a
program to run to the completion.
✱ Space complexity: It is the amount of memory space required by an algorithm,
during a course of its execution. Space complexity is required in situations when
limited memory is available and for the multi user system.
Data Search: Consider an inventory size of 106 items in a store; if our application
needs to search for a particular item, it needs to traverse 106 items every time, results in
slowing down the search process.
Multiple requests: If thousands of users are searching the data simultaneously in a web
server, it fails to process the requests.
In order to solve the above problems, data structures are used. Data is organized
to form a data structure in such a way that all items are not required to be searched
and required data can be searched instantly.
Data structures are important for the following reasons
1. Data structures are used in almost every program or software system.
2. Specific data structures are essential ingredients of many efficient algorithms, and
make possible the management of huge amounts of data, such as large integrated
collection of databases.
3. Some programming languages emphasize data structures, rather than algorithms, as
the key organizing factor in software design.
Advantages of Data Structures
Efficiency: Efficiency of a program depends upon the choice of data structures. For example:
suppose, we have some data and we need to perform the search for a particular record.
element. Hence, using array may not be very efficient here.
Reusability: Data structures are reusable, i.e. once we have implemented a particular
data structure, we can use it at any other place.
Abstraction: Data structure is specified by the ADT which provides a level of abstraction.
The client program uses the data structure through interface only, without getting into the
implementation details.
3.Classification of Data Structure
The data structure is classified into two different types, primitive and non-primitive data
structures is shown in Fig.1.
Primitive Data Structures
Simple data structure can be constructed with the help of primitive data structure.
A primitive data structure used to represent the standard data types of any one of the
computer languages. Variables, pointers, structures, unions, etc. are examples of primitive
data structures.
Non Primitive Data Structures
Non Primitive Data Structures are classified as linear or non-linear. Arrays, linked
lists, queues and stacks are linear data structures. Trees and Graphs are non-linear data
structures. Except arrays, all other data structures have many variations. Non Primitive data
structure can be constructed with the help of any one of the primitive data structure and
it is having a specific functionality. It can be designed by user.
Fig. 1 Classification of Data Structure
Queue: Queue is a linear list in which elements can be inserted only at one end called rear
and deleted only at the other end called front. It is a First-In-First-Out Linear data structure.
It is an abstract data structure, similar to stack. Queue is opened at both end therefore it
follows First-In-First-Out (FIFO) methodology for storing the data items.
Graphs: Graphs can be defined as the pictorial representation of the set of elements
(represented by vertices) connected by the links known as edges. A graph is different from tree
in the sense that a graph can have cycle while the tree cannot have the one.
2. Delete elements
✱ The data is generally stored in key sequence in a list which has a head structure
consisting of count, pointers and address of compare function needed to compare
the data in the list is shown in fig.3.
✱ The data node contains the pointer to a data structure and a self-referential pointer
which points to the next node in the list.
void *DataPtr;
} Node;
typedef struct{
int count;
Node *pos;
Node *head;
Node *rear;
} LIST;
typedefstruct node{
void *DataPtr;
} StackNode;
typedefstruct{ in
t count;
StackNode *top;
} STACK;
All operations take place at a single end that is top of the stack and following
operations can be performed:
• push() – Insert an element at one end of the stack called top.
• pop() – Remove and return the element at the top of the stack, if it is not
empty.
• peek() – Return the element at the top of the stack without removing it, if the
stack is not empty.
• size() – Return the number of elements in the stack.
• isEmpty() – Return true if the stack is empty, otherwise return false.
• isFull() – Return true if the stack is full, otherwise return false.
4.3 Queue ADT
✱ The queue Abstract Data Type (ADT) follows the basic design of the stack
abstract data type is shown in fig.6.
typedefstructnode {
void*DataPtr;
structnode *next;
} QueueNode;
typedefstruct {
QueueNode *front;
QueueNode *rear;
intcount;
} QUEUE;
✱ A Queue contains elements of the same type arranged in sequential order. Operations
take place at both ends, insertion is done at the end and deletion is done at the
front. Following operations can be performed:
• enqueue() – Insert an element at the end of the queue.
• dequeue() – Remove and return the first element of the queue, if the queue
is not empty.
• peek() – Return the element of the queue without removing it, if the queue
is not empty.
• size() – Return the number of elements in the queue.
• isEmpty() – Return true if the queue is empty, otherwise return false.
• isFull() – Return true if the queue is full, otherwise return false.
6.ARRAYS
The number of data items chunked together into a unit is known as data structure.
When the data structure consists simply a sequence of data items, the data structure of this
simple variety is referred as an array.
Definition: Array is a collection of homogenous (same data type) data elements that are
stored in contiguous memory locations.
Array Syntax
Syntax to declare an array:
✱ dataType [ ] arrayName;
arrayName= new dataType[n]; //keyword new performs dynamic memory location
(or)
✱ dataType [ ] arrayName = new dataType[n];
Example:
int [ ] x; x=new int [10]; (or)
int [] x=new int [10];
Array Initialization
The values of an array can be initialized as follows,
Example 1:
int [] j=new int [1]; j[0] =10;(or)int [] j= {25};
Example 2:
int [] myarray= {5, 10};
(iii) The name of array represents the starting address of the elements.
(iv) When data objects are stored in array, individual objects are selected by an
index.
(v) By default an array index starts from 0 and ends with (n-1). Index is also
referred as subscripts.
(vi) The size of the array is mentioned at the time of declaring array.
(vii) While declaring 2D array, number of columns should be specified whereas for
number of rows there is no such rule.
(viii) Size of array can’t be changed at run time.
6.STORAGE REPRESENTATION
An array is a set of homogeneous elements. Every element is referred by an index.
Memory storage locations of the elements are not arranged as a rectangular array with
rows and columns. Instead, they are arranged in a linear sequence beginning with
location 1, 2, 3 and so on. The elements are stored either column-by-column or row-by-row.
The first one is called column-major order and later is referred as row-major order.
Row 1 2 3
Index (1,1) (1,2) (1,3) (1,4) (2,1) (2,2) (2,3) (2,4) (3,1) (3,2) (3,3) (3,4)
Memory 100 102 104 106 108 110 112 114 116 118 120 122
Data 1 2 3 4 5 6 7 8 9 10 11 12
Data (A):
1 2 3 4
5 6 7 8
9 10 11 12
• Rows : 3
• Columns :4
Data (A):
1
Linear Arrangement of2 Array A
3 4
5 6 7 8
9 10 11 12
Column 1 2 3 4
Index (1,1) (2,1) (3,1) (1,2) (2,2) (3,2) (1,3) (2,3) (3,3) (1,4) (2,4) (3,4)
Memory 100 102 104 106 108 110 112 114 116 118 120 122
Data 1 5 9 2 6 10 3 7 11 4 8 12
4. for j = 0 to size
Example A={4,2,2,8,3,3,1}
1. Find out the maximum element (let it be max) from the given array.
2. Initialize an array of length max+1 with all elements 0. This array is used for
storing the count of the elements in the array.
3. Store the count of each element at their respective index in count array. For example:
th
If the count of element “4” occurs 2 times then 2 is stored in the 4 position in
th
the count array. If element “5” is not present in the array, then 0 is stored in 5
Example: A={56,78,34,23,70}
9. RECURSION
Recursion is a programming technique using function or algorithm that calls itself one or more
times until a specified condition is met at which time the rest of each repetition is processed
from the last one called to the first.
A simple recursive algorithm:
✱ Solves the base cases directly.
✱ Recurs with a simpler sub problem or sub problems.
✱ May do some extra work to convert the solution to the simpler sub problem into
a solution to the given problem.
Some Example Algorithms
1. Factorial
2. All permutations
3. Tree traversal
4. Binary Search
5. Quick Sort
6. Towers of Hanoi
9.1 Design Methodology and Implementation of Recursion
✱ Linear Recursion
✱ Binary Recursion
Linear Recursion:
Linear recursion is by far the most common form of recursion. In this style of recursion, the
function calls itself repeatedly until it hits the termination condition (Base condition).
Binary Recursion
Binary recursion is another popular and powerful method. This form of recursion has
the potential for calling itself twice instead of once as before. This is pretty useful in
scenarios such as binary tree traversal, generating a Fibonacci sequence, etc.
Tail Recursion
A function call is said to be tail recursive if there is nothing to do after the function
returns except return its value. Since the current recursive instance is done executing at
that point, saving its stack frame is a waste
For example the following C function print () is tail recursive.
Display n;
Print (n-1);
}
10. FIBONACCI SERIES
Fibonacci Series generates subsequent number by adding two previous numbers.
Fibonacci series starts from two numbers F0 & F1. The initial values of F0 & F1 can be
✱ 0 and 1
✱ 1 and 1 respectively.
Fibonacci RecursiveAlgorithm
11.FACTORIAL
The factorial of a positive number is the product of the integral values from 1 to the
number: Factorial of the given number can be calculated as:
Algorithm
RecursiveFactorial (n) if (N equals 0)
Return 1
else
Return (n*recursiveFactorial (n-1))
end if
end recursiveFactorial
Towers
Disks
Smalles
t
Largest
Fig.7 Tower of Hanoi
These rings are of different sizes and stacked upon in ascending order i.e. the
smaller one sits over the larger one. There are other variations of puzzle where the
number of disks increases, but the tower count remains the same.
7.1 Rules
The mission is to move all the disks to some another tower without violating the
sequence of arrangement. The below mentioned are few rules which are to be followed for
Tower of Hanoi
✱ Only one disk can be moved among the towers at any given time.
✱ Only the “top” disk can be removed.
✱ No large disk can sit over a small disk.
Steps for solving the Towers of Hanoi problem
The following steps are to be followed.
Step 1: Move n-1 disks from source to aux.
Step 2: Move nth disk from source to destination Step 3: Move n-1 disks from
aux to destination.
Following F i g . 8 illustrates the step by step movement of the disks to implement
Tower of Hanoi.
Step: 0
Step: 1
Step: 2
Step: 3
Step: 4
Step: 5
Step: 6
Done!