0% found this document useful (0 votes)
37 views

Unit-I (DS)

Engineering 2nd year

Uploaded by

tpayu740
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views

Unit-I (DS)

Engineering 2nd year

Uploaded by

tpayu740
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 67

Unit-I

Introduction

Data Structure can be defined as the group of data elements which provides an efficient way of
storing and organizing data in the computer so that it can be used efficiently. Some examples of
Data Structures are arrays, Linked List, Stack, Queue, etc. Data Structures are widely used in
almost every aspect of Computer Science i.e. Operating System, Compiler Design, Artificial
intelligence, Graphics and many more.

Data Structures are the main part of many computer science algorithms as they enable the
programmers to handle the data in an efficient way. It plays a vital role in enhancing the
performance of software or a program as the main function of the software is to store and
retrieve the user's data as fast as possible.

Basic Terminology

Data structures are the building blocks of any program or the software. Choosing the appropriate
data structure for a program is the most difficult task for a programmer. Following terminology
is used as far as data structures are concerned.

Data: Data can be defined as an elementary value or the collection of values, for example,
student's name and its id are the data about the student.

Group Items: Data items which have subordinate data items are called Group item, for example,
name of a student can have first name and the last name.

Record: Record can be defined as the collection of various data items, for example, if we talk
about the student entity, then its name, address, course and marks can be grouped together to
form the record for the student.

File: A File is a collection of various records of one type of entity, for example, if there are 60
employees in the class, then there will be 20 records in the related file where each record
contains the data about each employee.

Attribute and Entity: An entity represents the class of certain objects. it contains various
attributes. Each attribute represents the particular property of that entity.

Field: Field is a single elementary unit of information representing the attribute of an entity.

Need of Data Structures

As applications are getting complexed and amount of data is increasing day by day, there may
arise the following problems:
Processor speed: To handle very large amount of data, high speed processing is required, but as
the data is growing day by day to the billions of files per entity, processor may fail to deal with
that much amount of data.

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 on a web server,
then there are the chances that a very large server can be failed during that process

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.

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. In that
case, if we organize our data in an array, we will have to search sequentially element by element.
hence, using array may not be very efficient here. There are better data structures which can
make the search process efficient like ordered array, binary search tree or hash tables.

Reusability: Data structures are reusable, i.e. once we have implemented a particular data
structure, we can use it at any other place. Implementation of data structures can be compiled
into libraries which can be used by different clients.

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.

Elementary data organization:


Linear Data Structures: A data structure is called linear if all of its elements are arranged in the
linear order. In linear data structures, the elements are stored in non-hierarchical way where each
element has the successors and predecessors except the first and last element.

Types of Linear Data Structures are given below:


Arrays: An array is a collection of similar type of data items and each data item is called an
element of the array. The data type of the element may be any valid data type like char, int, float
or double.

The elements of array share the same variable name but each one carries a different index
number known as subscript. The array can be one dimensional, two dimensional or
multidimensional.

The individual elements of the array age are:

age[0], age[1], age[2], age[3],......... age[98], age[99].

Linked List: Linked list is a linear data structure which is used to maintain a list in the memory.
It can be seen as the collection of nodes stored at non-contiguous memory locations. Each node
of the list contains a pointer to its adjacent node.

Stack: Stack is a linear list in which insertion and deletions are allowed only at one end,
called top.

A stack is an abstract data type (ADT), can be implemented in most of the programming
languages. It is named as stack because it behaves like a real-world stack, for example: - piles of
plates or deck of cards etc.

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 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.

Non Linear Data Structures: This data structure does not form a sequence i.e. each item or
element is connected with two or more other items in a non-linear arrangement. The data
elements are not arranged in sequential structure.

Types of Non Linear Data Structures are given below:

Trees: Trees are multilevel data structures with a hierarchical relationship among its elements
known as nodes. The bottommost nodes in the hierarchy are called leaf node while the topmost
node is called root node. Each node contains pointers to point adjacent nodes.

Tree data structure is based on the parent-child relationship among the nodes. Each node in the
tree can have more than one children except the leaf nodes whereas each node can have at most
one parent except the root node. Trees can be classified into many categories which will be
discussed later in this tutorial.
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.

Operations on data structure

1) Traversing: Every data structure contains the set of data elements. Traversing the data
structure means visiting each element of the data structure in order to perform some specific
operation like searching or sorting.

Example: If we need to calculate the average of the marks obtained by a student in 6 different
subjects, we need to traverse the complete array of marks and calculate the total sum, then we
will divide that sum by the number of subjects i.e. 6, in order to find the average.

2) Insertion: Insertion can be defined as the process of adding the elements to the data structure
at any location.

If the size of data structure is n then we can only insert n-1 data elements into it.

3) Deletion: The process of removing an element from the data structure is called Deletion. We
can delete an element from the data structure at any random location.

If we try to delete an element from an empty data structure then underflow occurs.

4) Searching: The process of finding the location of an element within the data structure is
called Searching. There are two algorithms to perform searching, Linear Search and Binary
Search. We will discuss each one of them later in this tutorial.

5) Sorting: The process of arranging the data structure in a specific order is known as Sorting.
There are many algorithms that can be used to perform sorting, for example, insertion sort,
selection sort, bubble sort, etc.

6) Merging: When two lists List A and List B of size M and N respectively, of similar type of
elements, clubbed or joined to produce the third list, List C of size (M+N), then this process is
called merging.

Built-in Data types are those data types that are pre-defined by the programming language. Most
languages have native data types that are created for ease of execution of data. Such Data types are
called Built-in Data Types. These data types can be used directly in the program without the hassle of
creating them. Every programming language has its own specific set of built-in data types.

The term Built-in itself tells us that these categories of data types are defined by the programming
language at prior. Built-in Data types are those data types that can be directly used by the
programmer to declare and store different variables in a program.
They are also called Primary or Primitive Data Types. These Data types are believed to be one of
the fastest modes to execute operations on Data. The syntax used for defining these data types is
different for each programming language.

Real-Time Example of Built-in Data type

Suppose we want to create an automatic exam grading system for the students of a school. The data
which we require will be Names, Roll numbers, Class, Division, Subjects, Marks, Grades. This data
consists of various categories of data like Alphabets, Strings, Characters, Integers, Decimal
numbers, Symbols, etc. For this purpose, we can use the built-in data types which are provided by
the programming languages. This data can be fed into the program by using the built-in data types
such that the system finds it easy to accept, calculate, interpret and give results to the user.

Different Built-in Data Types

Int, char, float, double, Boolean, void – are the most basic and common built-in data types in every
programming language. Other than these if you want to work with complex data categories, you
will have to define them yourself. Let’s look at these data types in depth-

1. Int

This Built-in data type represents an integer number. It does not support any decimal or fractional
number. Generally, Int has been allocated 4 bytes/32 bits of memory space. Integer numbers can
contain Positive as well as Negative numbers.
Int Data Type is further divided into 2 type –

Signed Int – Allows positive as well as negative numbers.

Unsigned Int – Allows only positive numbers.

Ex:- 29, -50, 1947, 50384

2. Char

This data type accepts character values from the user. These characters include single letter, digit,
symbol, special characters, etc. Char data type occupies 2 bytes/16 bits of memory space.

Ex:- ‘A’, ‘$’, ‘g’, ‘5’

#include <stdio.h>

int main()

char ch; ch = 'A';

printf("The value of ch : %c", ch);

return 0;

3. Float

Float data type represents numbers that are in decimal format. They are commonly called floating-
point numbers. Float takes up 4 bytes/32 bits of memory space.

Ex:- 25.56, 785.383, -3674.7358, -10


#include <stdio.h>

int main()

float number;

printf("Enter a real number: ");

scanf("%f",&number);

printf("The number is %f",number);

return 0;

4. Boolean

This data type consists of only 2 values: True or False. It is a logical type of built-in data type. The
default value of Boolean data type is False.

5. Double

It is a variant of the Floating-point data type which is also used to represent fractional and decimal
numbers. Generally, 8 bytes/64 bits of memory space is allocated to it.

6. Void

This data type is widely used in C and C++ languages. It indicates that it has no value/empty. This
data type is mainly used as a return type for functions that do not return a value to the caller
function.

Type Conversion
The process in which one pre-defined type of expression is converted into another type is called
conversion. There are two types of conversion in C.

1. Implicit conversion
2. Explicit conversion

Implicit conversion
Data type can be mixed in the expression. For example
double a;
int b = 5;
float c = 8.5;
a = b * c;
When two operands of different type are encountered in the same expression, the lower type
variable is converted to the higher type variable. The following table shows the order of data
types.

Order of data types

Data type order


long double
double (highest)
float
long To
int
char (lowest)

The int value of b is converted to type float and stored in a temporary variable before being
multiplied by the float variable c. The result is then converted to double so that it can be assigned
to the double variable a.
Explicit conversion
It is also called type casting. It temporarily changes a variable data type from its declared data
type to a new one. It may be noted here that type casting can only be done on the right hand side
the assignment statement.
totalPay = (double)salary + bonus;

Algorithm It is a step-by-step procedure, which defines a set of instructions to be executed in a


certain order to get the desired output. Algorithms are generally created independent of
underlying languages, i.e. an algorithm can be implemented in more than one programming
language.
From the data structure point of view, following are some important categories of algorithms −
 Search − Algorithm to search an item in a data structure.
 Sort − Algorithm to sort items in a certain order.
 Insert − Algorithm to insert item in a data structure.
 Update − Algorithm to update an existing item in a data structure.
 Delete − Algorithm to delete an existing item from a data structure.

Characteristics of an Algorithm

Not all procedures can be called an algorithm. An algorithm should have the following
characteristics −
 Unambiguous − Algorithm should be clear and unambiguous. Each of its steps (or
phases), and their inputs/outputs should be clear and must lead to only one meaning.
 Input − An algorithm should have 0 or more well-defined inputs.
 Output − An algorithm should have 1 or more well-defined outputs, and should match
the desired output.
 Finiteness − Algorithms must terminate after a finite number of steps.
 Feasibility − Should be feasible with the available resources.
 Independent − An algorithm should have step-by-step directions, which should be
independent of any programming code.

How to Write an Algorithm?

There are no well-defined standards for writing algorithms. Rather, it is problem and resource
dependent. Algorithms are never written to support a particular programming code.
As we know that all programming languages share basic code constructs like loops (do, for,
while), flow-control (if-else), etc. These common constructs can be used to write an algorithm.
We write algorithms in a step-by-step manner, but it is not always the case. Algorithm writing is
a process and is executed after the problem domain is well-defined. That is, we should know the
problem domain, for which we are designing a solution.
Example
Let's try to learn algorithm-writing by using an example.
Problem − Design an algorithm to add two numbers and display the result.
Step 1 − START
Step 2 − declare three integers a, b & c
Step 3 − define values of a & b
Step 4 − add values of a & b
Step 5 − store output of step 4 to c
Step 6 − print c
Step 7 − STOP
Algorithms tell the programmers how to code the program. Alternatively, the algorithm can be
written as −
Step 1 − START ADD
Step 2 − get values of a & b
Step 3 − c ← a + b
Step 4 − display c
Step 5 − STOP
In design and analysis of algorithms, usually the second method is used to describe an algorithm.
It makes it easy for the analyst to analyze the algorithm ignoring all unwanted definitions. He
can observe what operations are being used and how the process is flowing.
Writing step numbers, is optional.
We design an algorithm to get a solution of a given problem. A problem can be solved in more
than one ways.

Hence, many solution algorithms can be derived for a given problem. The next step is to analyze
those proposed solution algorithms and implement the best suitable solution.

Algorithm Analysis

Efficiency of an algorithm can be analyzed at two different stages, before implementation and
after implementation. They are the following −
 A Priori Analysis − This is a theoretical analysis of an algorithm. Efficiency of an
algorithm is measured by assuming that all other factors, for example, processor speed,
are constant and have no effect on the implementation.
 A Posterior Analysis − This is an empirical analysis of an algorithm. The selected
algorithm is implemented using programming language. This is then executed on target
computer machine. In this analysis, actual statistics like running time and space required,
are collected.
We shall learn about a priori algorithm analysis. Algorithm analysis deals with the execution or
running time of various operations involved. The running time of an operation can be defined as
the number of computer instructions executed per operation.
Computer resources are limited that should be utilized efficiently. The efficiency of an algorithm
is defined as the number of computational resources used by the algorithm. An algorithm must
be analyzed to determine its resource usage. The efficiency of an algorithm can be measured
based on the usage of different resources.

For maximum efficiency of algorithm we wish to minimize resource usage. The important
resources such as time and space complexity cannot be compared directly, so time and space
complexity could be considered for an algorithmic efficiency.

Method for determining Efficiency

The efficiency of an algorithm depends on how efficiently it uses time and memory space.

The time efficiency of an algorithm is measured by different factors. For example, write a
program for a defined algorithm, execute it by using any programming language, and measure
the total time it takes to run. The execution time that you measure in this case would depend on a
number of factors such as:

· Speed of the machine


· Compiler and other system Software tools
· Operating System

· Programming language used

· Volume of data required


However, to determine how efficiently an algorithm solves a given problem, you would like to
determine how the execution time is affected by the nature of the algorithm. Therefore, we need
to develop fundamental laws that determine the efficiency of a program in terms of the nature of
the underlying algorithm.

Time and Space Complexity

Suppose X is an algorithm and n is the size of input data, the time and space used by the
algorithm X are the two main factors, which decide the efficiency of X.
 Time Factor − Time is measured by counting the number of key operations such as
comparisons in the sorting algorithm.
 Space Factor − Space is measured by counting the maximum memory space required by
the algorithm.
The complexity of an algorithm f(n) gives the running time and/or the storage space required by
the algorithm in terms of n as the size of input data.
Space Complexity

Space complexity of an algorithm represents the amount of memory space required by the
algorithm in its life cycle. The space required by an algorithm is equal to the sum of the
following two components −
 A fixed part that is a space required to store certain data and variables, that are
independent of the size of the problem. For example, simple variables and constants
used, program size, etc.
 A variable part is a space required by variables, whose size depends on the size of the
problem. For example, dynamic memory allocation, recursion stack space, etc.
Space complexity S(P) of any algorithm P is S(P) = C + SP(I), where C is the fixed part and S(I)
is the variable part of the algorithm, which depends on instance characteristic I. Following is a
simple example that tries to explain the concept −
Algorithm: SUM(A, B)
Step 1 - START
Step 2 - C ← A + B + 10
Step 3 - Stop
Here we have three variables A, B, and C and one constant. Hence S(P) = 1 + 3. Now, space
depends on data types of given variables and constant types and it will be multiplied accordingly.

Time Complexity

Time complexity of an algorithm represents the amount of time required by the algorithm to run
to completion. Time requirements can be defined as a numerical function T(n), where T(n) can
be measured as the number of steps, provided each step consumes constant time.
For example, addition of two n-bit integers takes n steps. Consequently, the total computational
time is T(n) = c ∗ n, where c is the time taken for the addition of two bits. Here, we observe that
T(n) grows linearly as the input size increases.

Space-Time tradeoff

A space-time or time-memory trade-off is a way of solving in less time by using more storage
space or by solving a given algorithm in very little space by spending more time.

To solve a given programming problem, many different algorithms may be used. Some of these
algorithms may be extremely time-efficient and others extremely space-efficient.

Time/space trade off refers to a situation where you can reduce the use of memory at the cost of
slower program execution, or reduce the running time at the cost of increased memory usage.
Asymptotic notations:

It tells us how good an algorithm is when compared with another algorithm. We cannot directly

compare two algorithms side by side. It heavily depends on the tools and the hardware we use for

comparisons, such as the Operating System, CPU model, processor generation, etc. Even if we

calculate time and space for two algorithms running on the same system, their time and space

complexity may be affected by the subtle changes in the system environment. Therefore, we

use Asymptotic analysis to compare space and time complexity. It analyzes two algorithms

based on changes in their performance concerning the increment or decrement in the input size.

Primarily there are three types of Asymptotic notations:

1. Big-Oh (O) notation.

2. Big Omega (Ω) notation.

3. Big Theta (Θ) notation

1. Big oh notation (O):


It is define as upper bound and upper bound on an algorithm is the most amount of time
required ( the worst case performance).
Big oh notation is used to describe asymptotic upper bound.
Mathematically, if f(n) describes the running time of an algorithm; f(n) is O(g(n)) if there
exist positive constant C and n0 such that,
0 <= f(n) <= Cg(n) for all n >= n0
n = used to give upper bound an a function.
If a function is O(n), it is automatically O(n-square) as well.
Graphic example for Big oh (O) :
2. Big Omega notation (Ω) :
It is define as lower bound and lower bound on an algorithm is the least amount of time
required ( the most efficient way possible, in other words best case).
Just like O notation provide an asymptotic upper bound, Ω notation provides asymptotic
lower bound.

Let f(n) define running time of an algorithm;


f(n) is said to be Ω(g (n)) if there exists positive constant C and (n0) such that
0 <= Cg(n) <= f(n) for all n >= n0
n = used to given lower bound on a function
If a function is Ω(n-square) it is automatically Ω(n) as well.
Graphical example for Big Omega (Ω):

3. Big Theta notation (Θ) :


It is define as tightest bound and tightest bound is the best of all the worst case times that the
algorithm can take.
Let f(n) define running time of an algorithm.
f(n) is said to be Θ(g(n)) if f(n) is O(g(n)) and f(n) is Ω(g(n)).
Mathematically,
0 <= f(n) <= C1g(n) for n >= n0
0 <= C2g(n) <= f(n) for n >= n0
Merging both the equation, we get :
0 <= C2g(n) <= f(n) <= C1g(n) for n >= n0
The equation simply means there exist positive constants C1 and C2 such that f(n) is
sandwich between C2 g(n) and C1g(n).

Graphic example of Big Theta (Θ):

Difference Between Big oh, Big Omega and Big Theta :

S.No
.
Big Oh (O) Big Omega (Ω) Big Theta (Θ)
It is like (<=)
rate of growth of an algorithm It is like (>=) It is like (==)
is less than or equal to a rate of growth is greater than meaning the rate of growth
1. specific value. or equal to a specified value. is equal to a specified value.
2. The upper bound of algorithm The algorithm’s lower bound The bounding of function
is represented by Big O is represented by Omega from above and below is
notation. Only the above notation. The asymptotic represented by theta
function is bounded by Big O. lower bond is given by Omega notation. The exact
asymptotic upper bond is it notation. asymptotic behavior is done
given by Big O notation. by this theta notation.
Big Omega (Ω) – Lower Big Theta (Θ) – Tight
3. Big oh (O) – Upper Bound Bound Bound
It is define as lower bound and
It is define as upper bound and lower bound on an algorithm It is define as tightest bound
upper bound on an algorithm is is the least amount of time and tightest bound is the
the most amount of time required ( the most efficient best of all the worst case
required ( the worst case way possible, in other words times that the algorithm can
4. performance). best case). take.
Mathematically: Big Oh is 0 Mathematically: Big Omega is Mathematically – Big Theta
<= f(n) <= Cg(n) for all n >= 0 <= Cg(n) <= f(n) for all n >= is 0 <= C2g(n) <= f(n) <=
5. n0 n0 C1g(n) for n >= n0

Best case, Worst case, and Average case in Asymptotic Analysis:

1. Best Case: It defines as the condition that allows an algorithm to complete the execution of
statements in the minimum amount of time. In this case, the execution time acts as a lower
bound on the algorithm’s time complexity.

2. Average Case: In the average case, we get the sum of running times on every possible input
combination and then take the average. In this case, the execution time acts as both lower
bound and upper bound on the algorithm’s time complexity.

3. Worst Case: It defines as the condition that allows an algorithm to complete the execution of
statements in the maximum amount of time. In this case, the execution time acts as an upper
bound on the algorithm’s time complexity.
Abstract Data Type: Data types such as int, float, double, long, etc. are considered to be
in-built data types and we can perform basic operations with them such as addition,
subtraction, division, multiplication, etc. Now there might be a situation when we need
operations for our user-defined data type which have to be defined. These operations can be
defined only as and when we require them. So, in order to simplify the process of solving
problems, we can create data structures along with their operations, and such data structures
that are not in-built are known as Abstract Data Type (ADT).
Abstract Data type (ADT) is a type (or class) for objects whose behavior is defined by a set of
values and a set of operations. The definition of ADT only mentions what operations are to be
performed but not how these operations will be implemented. It does not specify how data
will be organized in memory and what algorithms will be used for implementing the
operations. It is called “abstract” because it gives an implementation-independent view.

The process of providing only the essentials and hiding the details is known as abstraction.
The user of data type does not need to know how that data type is implemented, for example,
we have been using Primitive values like int, float, char data types only with the knowledge
that these data type can operate and be performed on without any idea of how they are
implemented.
So a user only needs to know what a data type can do, but not how it will be implemented.
Think of ADT as a black box which hides the inner structure and design of the data type. Now
we’ll define three ADTs namely List ADT, Stack ADT, Queue ADT.
1. List ADT
 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.
 The data node contains the pointer to a data structure and a self-referential
pointer which points to the next node in the list.
 The List ADT Functions is given below:
 get() – Return an element from the list at any given position.
 insert() – Insert an element at any position of the list.
 remove() – Remove the first occurrence of any element from a non-empty list.
 removeAt() – Remove the element at a specified location from a non-empty list.
 replace() – Replace an element at any position by another element.
 size() – Return the number of elements in the list.
 isEmpty() – Return true if the list is empty, otherwise return false.
 isFull() – Return true if the list is full, otherwise return false.
2. Stack ADT
 In Stack ADT Implementation instead of data being stored in each node, the pointer to
data is stored.
 The program allocates memory for the data and address is passed to the stack ADT.
 The head node and the data nodes are encapsulated in the ADT. The calling function
can only see the pointer to the stack.
 The stack head structure also contains a pointer to top and count of number of entries
currently in stack.
 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.
3. Queue ADT
 The queue abstract data type (ADT) follows the basic design of the stack abstract data
type.
 Each node contains a void pointer to the data and the link pointer to the next element
in the queue. The program’s responsibility is to allocate memory for storing the data.
 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.

Features of ADT:
 Abstraction: The user does not need to know the implementation of the data structure.
 Better Conceptualization: ADT gives us a better conceptualization of the real world.
 Robust: The program is robust and has the ability to catch errors.

Array:

Arrays are defined as the collection of similar types of data items stored at contiguous memory
locations. It is one of the simplest data structures where each data element can be randomly
accessed by using its index number.

In C programming, they are the derived data types that can store the primitive type of data such
as int, char, double, float, etc. For example, if we want to store the marks of a student in 6
subjects, then we don't need to define a different variable for the marks in different subjects.
Instead, we can define an array that can store the marks in each subject at the contiguous
memory locations.

Properties of array

There are some of the properties of an array that are listed as follows -
o Each element in an array is of the same data type and carries the same size that is 4 bytes.

o Elements in the array are stored at contiguous memory locations from which the first
element is stored at the smallest memory location.
o Elements of the array can be randomly accessed since we can calculate the address of
each element of the array with the given base address and the size of the data element.

Types of Array: There are mainly two types of the array:


 One Dimensional (1D) Array
 Multidimensional Array : It consists 2D & 3D array.

One Dimensional Array :


 It is a list of the variable of similar data types.
 It allows random access and all the elements can be accessed with the help of their index.
 The size of the array is fixed.
 For a dynamically sized array, vector can be used in C++.
 Representation of 1D array:

Two Dimensional Array:


 It is a list of lists of the variable of the same data type.
 It also allows random access and all the elements can be accessed with the help of their
index.
 It can also be seen as a collection of 1D arrays. It is also known as the Matrix.
 Its dimension can be increased from 2 to 3 and 4 so on.
 They all are referred to as a multi-dimension array.
 The most common multidimensional array is a 2D array.
 Representation of 2 D array:
Two-dimensional array

int arr[5][4]={ {1,2,3},{2,3,4},{3,4,5},{4,5,6},{5,6,7}};

Program in C to implement Two dimensional Array

int main(){
int i=0,j=0;
int arr[5][4]={{1,2,3},{2,3,4},{3,4,5},{4,5,6},{5,6,7}};
//traversing 2D array
for(i=0;i< 5;i++){
for(j=0;j< 4;j++){
printf("arr[%d] [%d] = %d \n",i,j,arr[i][j]);
}//end of j
}//end of i
return 0;
}

Three dimensional array

int arr2[10][20][30];
Initialization of the Multidimensional array

int test[2][3][4] = {{ {5, 6, 1, 9}, {10, -3, 91, 61}, {73, 32, 83, 22} },{ {13, 43, 56, 36}, {25, 9, 9
{39, 21, 74, 6} } };

Three Dimensional Arrays


Program in C to implement Three-dimensional array
int main()
{
int i, j, k, test[2][3][4];
printf("Enter 24 values for 3-D array: \n");
for(i = 0; i<2; ++i) {
for (j = 0; j <3; ++j) {
for(k = 0; k < 4; ++k ) {
scanf("%d", &test[i][j][k]);
}
}
}
printf("\nDisplaying the values of 3-D array:\n");
for(i = 0; i < 2; ++i) {
for (j = 0; j < 3; ++j) {
for(k = 0; k <4; ++k ) {
printf("test[%d][%d][%d] = %d\n", i, j, k, test[i][j][k]);
}
}
}
return 0;
}

Representation of an array

We can represent an array in various ways in different programming languages. As an


illustration, let's see the declaration of array in C language -

As per the above illustration, there are some of the following important points

o Index starts with 0.

o The array's length is 10, which means we can store 10 elements.

o Each element in the array can be accessed via its index.

Why are arrays required?

Arrays are useful because -

o Sorting and searching a value in an array is easier.

o Arrays are best to process multiple values quickly and easily.

o Arrays are good for storing multiple values in a single variable - In computer
programming, most cases require storing a large number of data of a similar type. To
store such an amount of data, we need to define a large number of variables. It would be
very difficult to remember the names of all the variables while writing the programs.
Instead of naming all the variables with a different name, it is better to define an array
and store all the elements into it.

Memory allocation of an array


1-D Array: As stated above, all the data elements of an array are stored at contiguous locations
in the main memory. The name of the array represents the base address or the address of the first
element in the main memory. Each element of the array is represented by proper indexing.

We can define the indexing of an array in the below ways -

1. 0 (zero-based indexing): The first element of the array will be arr[0].

2. 1 (one-based indexing): The first element of the array will be arr[1].

3. n (n - based indexing): The first element of the array can reside at any random index
number.

In the above image, we have shown the memory allocation of an array arr of size 5. The array
follows a 0-based indexing approach. The base address of the array is 100 bytes. It is the address
of arr[0]. Here, the size of the data type used is 4 bytes; therefore, each element will take 4 bytes
in the memory.

How to access an element from the array?

We required the information given belo

w to access any random element from the array -

o Base Address of the array.

o Size of an element in bytes.

o Type of indexing, array follows.

The formula to calculate the address to access an array element -

1. Byte address of element A[i] = base address + size * ( i - first index)


Here, size represents the memory taken by the primitive data types. As an instance, int takes 2
bytes, float takes 4 bytes of memory space in C programming.

We can understand it with the help of an example -

Q. Suppose an array, A[-10 ..... +2 ] having Base address (BA) = 999 and size of an element = 2
bytes, find the location of A[-1].

L(A[-1]) = 999 + 2 x [(-1) - (-10)]

= 999 + 18

= 1017

2-D Array

Row major order and column major order:

To find the address of any element in a 2-Dimensional array there are the following two
ways-
1. Row Major Order
2. Column Major Order
1. Row Major Order:
Row major ordering assigns successive elements, moving across the rows and then down the
next row, to successive memory locations. In simple language, the elements of an array are
stored in a Row-Wise fashion.

To find the address of the element using row-major order uses the following formula:
Address of A[I][J] = B + W * ((I – LR) * N + (J – LC))

I = Row Subset of an element whose address to be found,


J = Column Subset of an element whose address to be found,
B = Base address,
W = Storage size of one element store in an array(in byte),
LR = Lower Limit of row/start row index of the matrix(If not given assume it as zero),
LC = Lower Limit of column/start column index of the matrix(If not given assume it as zero),
N = Number of column given in the matrix.
Example: Given an array, arr[1………10][1………15] with base value 100 and the size of
each element is 1 Byte in memory. Find the address of arr[8][6] with the help of row-major
order.
Solution:
Given:
Base address B = 100

Storage size of one element store in any array W = 1 Bytes

Row Subset of an element whose address to be found I = 8

Column Subset of an element whose address to be found J = 6

Lower Limit of row/start row index of matrix LR = 1

Lower Limit of column/start column index of matrix = 1

Number of column given in the matrix N = Upper Bound – Lower Bound + 1

= 15 – 1 + 1

= 15
Formula:
Address of A[I][J] = B + W * ((I – LR) * N + (J – LC))
Solution:
Address of A[8][6] = 100 + 1 * ((8 – 1) * 15 + (6 – 1))
= 100 + 1 * ((7) * 15 + (5))
= 100 + 1 * (110)
Address of A[I][J] = 210
2. Column Major Order:
If elements of an array are stored in a column-major fashion means moving across the column
and then to the next column then it’s in column-major order. To find the address of the
element using column-major order use the following formula:
Address of A[I][J] = B + W * ((J – LC) * M + (I – LR))
I = Row Subset of an element whose address to be found,
J = Column Subset of an element whose address to be found,
B = Base address,
W = Storage size of one element store in any array(in byte),
LR = Lower Limit of row/start row index of matrix(If not given assume it as zero),
LC = Lower Limit of column/start column index of matrix(If not given assume it as zero),
M = Number of rows given in the matrix.
Example: Given an array arr[1………10][1………15] with a base value of 100 and the size
of each element is 1 Byte in memory find the address of arr[8][6] with the help of column-
major order.
Solution:
Given:
Base address B = 100

Storage size of one element store in any array W = 1 Bytes

Row Subset of an element whose address to be found I = 8

Column Subset of an element whose address to be found J = 6

Lower Limit of row/start row index of matrix LR = 1

Lower Limit of column/start column index of matrix = 1

Number of column given in the matrix M = Upper Bound – Lower Bound + 1

= 10 – 1 + 1

= 10
Formula: used

Address of A[I][J] = B + W * ((J – LC) * M + (I – LR))

Address of A[8][6] = 100 + 1 * ((6 – 1) * 10 + (8 – 1))

= 100 + 1 * ((5) * 10 + (7))

= 100 + 1 * (57)

Address of A[I][J] = 157


From the above examples, it can be observed that for the same position two different address
locations are obtained that’s because in row-major order movement is done across the rows
and then down to the next row, and in column-major order, first move down to the first
column and then next column. So both the answers are right.
So it’s all based on the position of the element whose address is to be found for some cases
the same answers is also obtained with row-major order and column-major order and for some
cases, different answers are obtained.
3-D Array :
A 3-Dimensional array is a collection of 2-Dimensional arrays. It is specified by using three
subscripts:
1. Block size
2. Row size
3. Column size
More dimensions in an array mean more data can be stored in that array.
Example:

To find the address of any element in 3-Dimensional arrays there are the following two ways-
 Row Major Order
 Column Major Order
1. Row Major Order:
To find the address of the element using row-major order, use the following formula:
Address of A[i][j][k] = B + W (M * N(i-x) + N *(j-y) + (k-z))
Here:
B = Base Address (start address)

W = Weight (storage size of one element stored in the array)


M = Row (total number of rows)
N = Column (total number of columns)
P = Width (total number of cells depth-wise)
x = Lower Bound of Row
y = Lower Bound of Column
z = Lower Bound of Width
Example: Given an array, arr[1:9, -4:1, 5:10] with a base value of 400 and the size of each
element is 2 Bytes in memory find the address of element arr[5][-1][8] with the help of row-
major order?
Solution:
Given:
Row Subset of an element whose address to be found I = 5
Column Subset of an element whose address to be found J = -1
Block Subset of an element whose address to be found K = 8
Base address B = 400
Storage size of one element store in any array(in Byte) W = 2
Lower Limit of row/start row index of matrix x = 1
Lower Limit of column/start column index of matrix y = -4
Lower Limit of blocks in matrix z = 5
M = Upper Bound – Lower Bound + 1 = 1 – (-4) + 1 = 6
N = Upper Bound – Lower Bound + 1 = 10 – 5 + 1 = 6

Formula used:
Address of[I][J][K] =B + W (M * N(i-x) + N *(j-y) + (k-z))
Solution:
Address of[][][] = 400 + 2 * {[6 * 6 * (5 – 1)] + 6 * [(-1 + 4)]} + [8 – 5]

= 400 + 2 * ((4 * 6 + 3) * 6 + 3)

= 400 + 2 * (165)

= 730
2. Column Major Order:
To find the address of the element using column-major order, use the following formula:1
Address of A[i][j][k = B + W(M * N(i – x) + M *(k – z) + (j – y))
Here:
B = Base Address (start address)
W = Weight (storage size of one element stored in the array)
M = Row (total number of rows)
N = Column (total number of columns)
P = Width (total number of cells depth-wise)
x = Lower Bound of Row
y = Lower Bound of Column
z = Lower Bound of Width
Example: Given an array arr[1:8, -5:5, -10:5] with a base value of 400 and the size of each
element is 4 Bytes in memory find the address of element arr[3][3][3] with the help of
column-major order?
Solution:
Given:
Row Subset of an element whose address to be found I = 3

Column Subset of an element whose address to be found J = 3

Block Subset of an element whose address to be found K = 3

Base address B = 400

Storage size of one element store in any array(in Byte) W = 4

Lower Limit of row/start row index of matrix x = 1

Lower Limit of column/start column index of matrix y = -5

Lower Limit of blocks in matrix z = -10

M = Upper Bound – Lower Bound + 1 = 5 + 5 + 1 = 11

N = Upper Bound – Lower Bound + 1 = 5 + 10 + 1 = 16

Formula used:

Address of[i][j][k] = B + W(M * N(i – x) + M * (k – z) + (j – y))


Solution:
Address of[3][3][3] = 400 + 4 * {[(3 – 1)] * 16 + [3 + 10] ]} * 11 + [3 + 5]

= 400 + 4 * ((32 + 13) * 11 + 8)

= 400 + 4 * (503)

= 400 + 2012

= 2412

Basic operations
Now, let's discuss the basic operations supported in the array -

o Traversal - This operation is used to print the elements of the array.

o Insertion - It is used to add an element at a particular index.

o Deletion - It is used to delete an element from a particular index.

o Search - It is used to search an element using the given index or by the value.

o Update - It updates an element at a particular index.

Traversal operation

This operation is performed to traverse through the array elements. It prints all array elements
one after another. We can understand it with the below program -

Insertion operation

This operation is performed to insert one or more elements into the array. As per the
requirements, an element can be added at the beginning, end, or at any index of the array. Now,
let's see the implementation of inserting an element into the array.
Deletion operation

As the name implies, this operation removes an element from the array and then reorganizes all
of the array elements.

Search operation

This operation is performed to search an element in the array based on the value or index.
1. #include <stdio.h>
2.
3. void main() {
4. int arr[5] = {18, 30, 15, 70, 12};
5. int item = 70, i, j=0 ;
6.
7. printf("Given array elements are :\n");
8.
9. for(i = 0; i<5; i++) {
10. printf("arr[%d] = %d, ", i, arr[i]);
11. }
12. printf("\nElement to be searched = %d", item);
13. while( j < 5){
14. if( arr[j] == item ) {
15. break;
16. }
17.
18. j = j + 1;
19. }
20.
21. printf("\nElement %d is found at %d position", item, j+1);
22. }

Output

Update operation

This operation is performed to update an existing array element located at the given index.

1. #include <stdio.h>
2.
3. void main() {
4. int arr[5] = {18, 30, 15, 70, 12};
5. int item = 50, i, pos = 3;
6.
7. printf("Given array elements are :\n");
8.
9. for(i = 0; i<5; i++) {
10. printf("arr[%d] = %d, ", i, arr[i]);
11. }
12.
13. arr[pos-1] = item;
14. printf("\nArray elements after updation :\n");
15.
16. for(i = 0; i<5; i++) {
17. printf("arr[%d] = %d, ", i, arr[i]);
18. }
19. }

Output

Complexity of Array operations

Time and space complexity of various array operations are described in the following table.

Time Complexity

Operation Average Case Worst Case

Access O(1) O(1)


Search O(n) O(n)

Insertion O(n) O(n)

Deletion O(n) O(n)

Space Complexity

In array, space complexity for worst case is O(n).

Advantages of Array

o Array provides the single name for the group of variables of the same type. Therefore, it
is easy to remember the name of all the elements of an array.
o Traversing an array is a very simple process; we just need to increment the base address
of the array in order to visit each element one by one.
o Any element in the array can be directly accessed by using the index.

Disadvantages of Array

o Array is homogenous. It means that the elements with similar data type can be stored in
it.
o In array, there is static memory allocation that is size of an array cannot be altered.

o There will be wastage of memory if we store less number of elements than the declared
size.

Applications of Arrays:

Below are some applications of arrays.


 Arrays are used to implement data structures like a stack, queue, etc.
 Arrays are used for matrices and other mathematical implementations.
 Arrays are used in lookup tables in computers.
 Arrays can be used for CPU scheduling.
Real-Time Applications of Array:
Below are some real-time applications of arrays.
 Contact lists on mobile phones.
 Matrices use arrays which are used in different fields like image processing, computer
graphics, and many more.
 Arrays are used in online ticket booking portals.
 Pages of book.
 IoT applications use arrays as we know that the number of values in an array will remain
constant, and also that the accessing will be faster.
 It is also utilised in speech processing, where each speech signal is represented by an
array.
 The viewing screen of any desktop/laptop is also a multidimensional array of pixels.

Applications of Array in C/C++:


 Arrays are used to implement vectors, and lists in C++ STL.
 Arrays are used as the base of all sorting algorithms.
 Arrays are used to implement other DS like a stack, queue, etc.
 Used for implementing matrices.
 Data structures like trees also sometimes use the array implementation since arrays are
easier to handle than pointers. For example, a segment tree uses array implementation.
 Binary search trees and balanced binary trees are used in data structures such as a heap,
map, and set, which can be built using arrays.
 Graphs are also implemented as arrays in the form of an adjacency matrix.

Applications of Array in Java:


 Arrays are good for implementing lists.
 Arrays can be used to determine the flow of the code.
 Arrays are better than pointers for tree implementation.

Applications of Array in C#:


 In C#, arrays are objects not just addressable contiguous regions of memory.
 Arrays are dynamically allocated in C#.

Sparse matrices and representation:

Sparse matrices are those matrices that have the majority of their elements equal to zero. In other
words, the sparse matrix can be defined as the matrix that has a greater number of zero elements
than the non-zero elements.

Now, the question arises: we can also use the simple matrix to store the elements, then why is the
sparse matrix required?

Why is a sparse matrix required if we can use the simple matrix to store elements?
There are the following benefits of using the sparse matrix -

Storage - We know that a sparse matrix contains lesser non-zero elements than zero, so less
memory can be used to store elements. It evaluates only the non-zero elements.

Computing time: In the case of searching in sparse matrix, we need to traverse only the non-
zero elements rather than traversing all the sparse matrix elements. It saves computing time by
logically designing a data structure traversing non-zero elements.

Representation of sparse matrix

Now, let's see the representation of the sparse matrix. The non-zero elements in the sparse matrix
can be stored using triplets that are rows, columns, and values. There are two ways to represent
the sparse matrix that are listed as follows -

o Array representation

o Linked list representation

Array representation of the sparse matrix

Representing a sparse matrix by a 2D array leads to the wastage of lots of memory. This is
because zeroes in the matrix are of no use, so storing zeroes with non-zero elements is wastage
of memory. To avoid such wastage, we can store only non-zero elements. If we store only non-
zero elements, it reduces the traversal time and the storage space.

In 2D array representation of sparse matrix, there are three fields used that are named as -

o Row - It is the index of a row where a non-zero element is located in the matrix.

o Column - It is the index of the column where a non-zero element is located in the matrix.

o Value - It is the value of the non-zero element that is located at the index (row, column).

Example -

Let's understand the array representation of sparse matrix with the help of the example given
below -
Consider the sparse matrix -

In the above figure, we can observe a 5x4 sparse matrix containing 7 non-zero elements and 13
zero elements. The above matrix occupies 5x4 = 20 memory space. Increasing the size of matrix
will increase the wastage space.

The tabular representation of the above matrix is given below -

In the above structure, first column represents the rows, the second column represents the
columns, and the third column represents the non-zero value. The first row of the table represents
the triplets. The first triplet represents that the value 4 is stored at 0th row and 1st column.
Similarly, the second triplet represents that the value 5 is stored at the 0th row and 3rd column.
In a similar manner, all triplets represent the stored location of the non-zero elements in the
matrix.

The size of the table depends upon the total number of non-zero elements in the given sparse
matrix. Above table occupies 8x3 = 24 memory space which is more than the space occupied by
the sparse matrix. So, what's the benefit of using the sparse matrix? Consider the case if the
matrix is 8*8 and there are only 8 non-zero elements in the matrix, then the space occupied by
the sparse matrix would be 8*8 = 64, whereas the space occupied by the table represented using
triplets would be 8*3 = 24.

Implementation of array representation of the sparse matrix

Now, let's see the implementation of array representation of sparse matrix in C language.

In the program below, we will show the tabular representation of the non-zero elements of the
sparse matrix stored in array.

Output
Linked List representation of the sparse matrix

In a linked list representation, the linked list data structure is used to represent the sparse matrix.
The advantage of using a linked list to represent the sparse matrix is that the complexity of
inserting or deleting a node in a linked list is lesser than the array.

Unlike the array representation, a node in the linked list representation consists of four fields.
The four fields of the linked list are given as follows -

o Row - It represents the index of the row where the non-zero element is located.

o Column - It represents the index of the column where the non-zero element is located.

o Value - It is the value of the non-zero element that is located at the index (row, column).

o Next node - It stores the address of the next node.

The node structure of the linked list representation of the sparse matrix is shown in the below
image -
Example -

Let's understand the linked list representation of sparse matrix with the help of the example given
below -

Consider the sparse matrix -

In the above figure, we can observe a 4x4 sparse matrix containing 5 non-zero elements and 11
zero elements. Above matrix occupies 4x4 = 16 memory space. Increasing the size of matrix will
increase the wastage space.

The linked list representation of the above matrix is given below -

In the above figure, the sparse matrix is represented in the linked list form. In the node, the first
field represents the index of the row, the second field represents the index of the column, the
third field represents the value, and the fourth field contains the address of the next node.

In the above figure, the first field of the first node of the linked list contains 0, which means
0th row, the second field contains 2, which means 2 nd column, and the third field contains 1 that is
the non-zero element. So, the first node represents that element 1 is stored at the 0 th row-
2nd column in the given sparse matrix. In a similar manner, all of the nodes represent the non-
zero elements of the sparse matrix.

Implementation of linked list representation of sparse matrix


Now, let's see the implementation of linked list representation of sparse matrix in Java.

1. class Node {
2. int row;
3. int col;
4. int value;
5. Node next;
6. Node(int r, int c, int val)
7. { row = r; col = c; this.value = val; }
8. }
9. public class Sparse{
10. public static void main(String[] args)
11. {
12. /*Assume a 4x4 sparse matrix */
13. int sparseMatrix[][] = {
14. {0, 0, 1, 2},
15. {3, 0, 0, 0},
16. {0, 4, 5, 0},
17. {0, 6, 0, 0}
18. };
19. Node start = null; /*Start with the empty list*/
20. Node tail = null;
21. int k = 0;
22. for (int i = 0; i < 4; i++)
23. for (int j = 0; j < 4; j++)
24. {
25. if (sparseMatrix[i][j] != 0) /*Pass only non-zero values*/
26. {
27. Node temp = new Node(i, j, sparseMatrix[i][j]);
28. temp.next = null;
29. if(start == null){
30. start = temp;
31. tail=temp;
32. }
33. else{
34. tail.next = temp;
35. tail = tail.next;
36. }
37. }
38. }
39. Node itr = start;
40. while(start != null){
41. System.out.println(start.row + " " + start.col + " " + start.value);
42. start = start.next;
43. }
44. }
45. }

Output

Every row in the output represents the node of the linked list. In every row of the below
screenshot, the first element represents the row index location of the non-zero element, the
second element represents the column index location of the non-zero element, and the third
element represents the non-zero element itself.
Linked List
A linked list is a sequence of data structures, which are connected together via links.
Linked List is a sequence of links which contains items. Each link contains a connection to
another link. Linked list is the second most-used data structure after array. Following are the
important terms to understand the concept of Linked List.
 Link − each link of a linked list can store a data called an element.
 Next − each link of a linked list contains a link to the next link called Next.
 LinkedList − A Linked List contains the connection link to the first link called First.

Linked List Representation

Linked list can be visualized as a chain of nodes, where every node points to the next node.

As per the above illustration, following are the important points to be considered.
 Linked List contains a link element called first.
 Each link carries a data field(s) and a link field called next.
 Each link is linked with its next link using its next link.
 Last link carries a link as null to mark the end of the list.

Uses of Linked List

o The list is not required to be contiguously present in the memory. The node can reside
anywhere in the memory and linked together to make a list. This achieves optimized
utilization of space.
o List size is limited to the memory size and doesn't need to be declared in advance.
o Empty node cannot be present in the linked list.
o We can store values of primitive types or objects in the singly linked list.

Why use linked list over array?

Till now, we were using array data structure to organize the group of elements that are to be
stored individually in the memory. However, Array has several advantages and disadvantages
which must be known in order to decide the data structure which will be used throughout the
program.
Array contains following limitations:

1. The size of array must be known in advance before using it in the program.
2. Increasing size of the array is a time taking process. It is almost impossible to expand the
size of the array at run time.
3. All the elements in the array need to be contiguously stored in the memory. Inserting any
element in the array needs shifting of all its predecessors.

Linked list is the data structure which can overcome all the limitations of an array. Using linked
list is useful because,

1. It allocates the memory dynamically. All the nodes of linked list are non-contiguously
stored in the memory and linked together with the help of pointers.
2. Sizing is no longer a problem since we do not need to define its size at the time of
declaration. List grows as per the program's demand and limited to the available memory
space.

Types of Linked List

Following are the various types of linked list.


 Simple Linked List − Item navigation is forward only. Singly linked list can be defined
as the collection of ordered set of elements. The number of elements may vary according
to need of the program. A node in the singly linked list consists of two parts: data part
and link part. Data part of the node stores actual information that is to be represented by
the node while the link part of the node stores the address of its immediate successor.

One way chain or singly linked list can be traversed only in one direction. In other words, we can
say that each node contains only next pointer, therefore we cannot traverse the list in the reverse
direction.

Consider an example where the marks obtained by the student in three subjects are stored in a
linked list as shown in the figure.
In the above figure, the arrow represents the links. The data part of every node contains the
marks obtained by the student in the different subject. The last node in the list is identified by the
null pointer which is present in the address part of the last node. We can have as many elements
we require, in the data part of the list.

Complexity

Data Time Complexity Space


Structure Complex
ity

Average Worst Worst

Access Search Insertion Deletion Access Search Insertion Deletion

Singly θ(n) θ(n) θ(1) θ(1) O(n) O(n) O(1) O(1) O(n)
Linked List

Operations on Singly Linked List

There are various operations which can be performed on singly linked list. A list of all such
operations is given below.

Node Creation
1. struct node
2. {
3. int data;
4. struct node *next;
5. };
6. struct node *head, *ptr;
7. ptr = (struct node *)malloc(sizeof(struct node *));

Insertion

The insertion into a singly linked list can be performed at different positions. Based on the
position of the new node being inserted, the insertion is

categorized into the following categories.

SN Operation Description

1 Insertion at It involves inserting any element at the front of the list. We just need to a
beginning few link adjustments to make the new node as the head of the list.

2 Insertion at end of It involves insertion at the last of the linked list. The new node can be
the list inserted as the only node in the list or it can be inserted as the last one.
Different logics are implemented in each scenario.

3 Insertion after It involves insertion after the specified node of the linked list. We need to
specified node skip the desired number of nodes in order to reach the node after which the
new node will be inserted. .

Deletion and Traversing

The Deletion of a node from a singly linked list can be performed at different positions. Based on
the position of the node being deleted, the operation is categorized into the following categories.

S Operation Description
N

1 Deletion at It involves deletion of a node from the beginning of the list. This is the
beginning simplest operation among all. It just need a few adjustments in the node
pointers.

2 Deletion at the end It involves deleting the last node of the list. The list can either be empty or
of the list full. Different logic is implemented for the different scenarios.

3 Deletion after It involves deleting the node after the specified node in the list. we need to
specified node skip the desired number of nodes to reach the node after which the node
will be deleted. This requires traversing through the list.

4 Traversing In traversing, we simply visit each node of the list at least once in order to
perform some specific operation on it, for example, printing data part of
each node present in the list.

5 Searching In searching, we match each element of the list with the given element. If
the element is found on any of the location then location of that element is
returned otherwise null is returned. .

Creation, insertion & deletion of Single Linked List (from pdf)

Doubly Linked List − Items can be navigated forward and backward. Doubly linked list is a
complex type of linked list in which a node contains a pointer to the previous as well as the next
node in the sequence. Therefore, in a doubly linked list, a node consists of three parts: node data,
pointer to the next node in sequence (next pointer), and pointer to the previous node (previous
pointer). A sample node in a doubly linked list is shown in the figure.

A doubly linked list containing three nodes having numbers from 1 to 3 in their data part, is
shown in the following image.
In C, structure of a node in doubly linked list can be given as :

1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. }

The prev part of the first node and the next part of the last node will always contain null

indicating end in each direction.

In a singly linked list, we could traverse only in one direction, because each node contains
address of the next node and it doesn't have any record of its previous nodes. However, doubly
linked list overcome this limitation of singly linked list. Due to the fact that, each node of the list
contains the address of its previous node, we can find all the details about the previous node as
well by using the previous address stored inside the previous part of each node.

Memory Representation of a doubly linked list

Memory Representation of a doubly linked list is shown in the following image. Generally,
doubly linked list consumes more space for every node and therefore, causes more expansive
basic operations such as insertion and deletion. However, we can easily manipulate the elements
of the list since the list maintains pointers in both the directions (forward and backward).

In the following image, the first element of the list that is i.e. 13 stored at address 1. The head
pointer points to the starting address 1. Since this is the first element being added to the list
therefore the prev of the list contains null. The next node of the list resides at address 4
therefore the first node contains 4 in its next pointer.
We can traverse the list in this way until we find any node containing null or -1 in its next part.

Operations on doubly linked list

Node Creation

1. struct node
2. {
3. struct node *prev;
4. int data;
5. struct node *next;
6. };
7. struct node *head;

All the remaining operations regarding doubly linked list are described in the following table.

S Operation Description
N

1 Insertion at beginning Adding the node into the linked list at beginning.

2 Insertion at end Adding the node into the linked list to the end.

3 Insertion after specified node Adding the node into the linked list after the specified node.

4 Deletion at beginning Removing the node from beginning of the list

5 Deletion at the end Removing the node from end of the list.

6 Deletion of the node having Removing the node which is present just after the node containing
given data the given data.

7 Searching Comparing each node data with the item to be searched and return
the location of the item in the list if the item found else return null.

8 Traversing Visiting each node of the list at least once in order to perform some
specific operation like searching, sorting, display, etc.

Creation, insertion & deletion of double Linked List (from pdf notes)

Circular Linked List − Last item contains link of the first element as next and the first element
has a link to the last element as previous. In a circular Singly linked list, the last node of the list
contains a pointer to the first node of the list. We can have circular singly linked list as well as
circular doubly linked list.

We traverse a circular singly linked list until we reach the same node where we started. The
circular singly liked list has no beginning and no ending. There is no null value present in the
next part of any of the nodes.

The following image shows a circular singly linked list.


Circular linked list are mostly used in task maintenance in operating systems. There are many
examples where circular linked list are being used in computer science including browser surfing
where a record of pages visited in the past by the user, is maintained in the form of circular
linked lists and can be accessed again on clicking the previous button.

Memory Representation of circular linked list:

In the following image, memory representation of a circular linked list containing marks of a
student in 4 subjects. However, the image shows a glimpse of how the circular list is being stored
in the memory. The start or head of the list is pointing to the element with the index 1 and
containing 13 marks in the data part and 4 in the next part. Which means that it is linked with the
node that is being stored at 4th index of the list.

However, due to the fact that we are considering circular linked list in the memory therefore the
last node of the list contains the address of the first node of the list.
We can also have more than one number of linked list in the memory with the different start
pointers pointing to the different start nodes in the list. The last node is identified by its next part
which contains the address of the start node of the list. We must be able to identify the last node
of any linked list so that we can find out the number of iterations which need to be performed
while traversing the list.

Operations on Circular Singly linked list:

Insertion

SN Operation Description

1 Insertion at beginning Adding a node into circular singly linked list at the beginning.

2 Insertion at the end Adding a node into circular singly linked list at the end.

Deletion & Traversing

S Operation Description
N

1 Deletion at Removing the node from circular singly linked list at the beginning.
beginning

2 Deletion at the end Removing the node from circular singly linked list at the end.

3 Searching Compare each element of the node with the given item and return the
location at which the item is present in the list otherwise return null.

4 Traversing Visiting each element of the list at least once in order to perform some
specific operation.

Creation, insertion & deletion of circular Linked List (from pdf notes)

Circular Doubly Linked List: Circular doubly linked list is a more complexed type of data
structure in which a node contains pointers to its previous node as well as the next node. Circular
doubly linked list doesn't contain NULL in any of the node. The last node of the list contains the
address of the first node of the list. The first node of the list also contains address of the last node
in its previous pointer.

A circular doubly linked list is shown in the following figure.

Due to the fact that a circular doubly linked list contains three parts in its structure therefore, it
demands more space per node and more expensive basic operations. However, a circular doubly
linked list provides easy manipulation of the pointers and the searching becomes twice as
efficient.

Memory Management of Circular Doubly linked list

The following figure shows the way in which the memory is allocated for a circular doubly
linked list. The variable head contains the address of the first element of the list i.e. 1 hence the
starting node of the list contains data A is stored at address 1. Since, each node of the list is
supposed to have three parts therefore; the starting node of the list contains address of the last
node i.e. 8 and the next node i.e. 4. The last node of the list that is stored at address 8 and
containing data as 6, contains address of the first node of the list as shown in the image i.e. 1. In
circular doubly linked list, the last node is identified by the address of the first node which is
stored in the next part of the last node therefore the node which contains the address of the first
node, is actually the last node of the list.
Operations on circular doubly linked list :

There are various operations which can be performed on circular doubly linked list. The node
structure of a circular doubly linked list is similar to doubly linked list. However, the operations
on circular doubly linked list are described in the following table.

SN Operation Description

1 Insertion at beginning Adding a node in circular doubly linked list at the beginning.

2 Insertion at end Adding a node in circular doubly linked list at the end.

3 Deletion at beginning Removing a node in circular doubly linked list from beginning.

4 Deletion at end Removing a node in circular doubly linked list at the end.

Creation, insertion & deletion of doubly circular Linked List (from pdf notes)

Basic Operations

Following are the basic operations supported by a list.


 Insertion − Adds an element at the beginning of the list.
 Deletion − Deletes an element at the beginning of the list.
 Display − Displays the complete list.
 Search − Searches an element using the given key.
 Delete − Deletes an element using the given key.

Insertion Operation
Adding a new node in linked list is a more than one step activity. We shall learn this with
diagrams here. First, create a node using the same structure and find the location where it has to
be inserted.

Imagine that we are inserting a node B (NewNode), between A (LeftNode) and C (RightNode).
Then point B.next to C −
NewNode.next −> RightNode;
It should look like this −

Now, the next node at the left should point to the new node.
LeftNode.next −> NewNode;

This will put the new node in the middle of the two. The new list should look like this −
Similar steps should be taken if the node is being inserted at the beginning of the list. While
inserting it at the end, the second last node of the list should point to the new node and the new
node will point to NULL.

Deletion Operation

Deletion is also a more than one step process. We shall learn with pictorial representation. First,
locate the target node to be removed, by using searching algorithms.

The left (previous) node of the target node now should point to the next node of the target node −
LeftNode.next −> TargetNode.next;

This will remove the link that was pointing to the target node. Now, using the following code, we
will remove what the target node is pointing at.
TargetNode.next −> NULL;

We need to use the deleted node. We can keep that in memory otherwise we can simply
deallocate memory and wipe off the target node completely.
Reverse Operation

This operation is a thorough one. We need to make the last node to be pointed by the head node
and reverse the whole linked list.

First, we traverse to the end of the list. It should be pointing to NULL. Now, we shall make it
point to its previous node −

We have to make sure that the last node is not the last node. So we'll have some temp node,
which looks like the head node pointing to the last node. Now, we shall make all left side nodes
point to their previous nodes one by one.

Except the node (first node) pointed by the head node, all nodes should point to their
predecessor, making them their new successor. The first node will point to NULL.

We'll make the head node point to the new first node by using the temp node.
Polynomial representation:
Linked list is a data structure that stores each element as an object in a node of the list. Every
note contains two parts data and links to the next node.
Polynomial is a mathematical expression that consists of variables and coefficients. For
example x^2 - 4x + 7
In the Polynomial linked list, the coefficients and exponents of the polynomial are defined as
the data node of the list.
For adding two polynomials that are stored as a linked list. We need to add the coefficients of
variables with the same power. In a linked list node contains 3 members, coefficient value link
to the next node.
a linked list that is used to store Polynomial looks like −
Polynomial: 4x7 + 12x2 + 45

This is how a linked list represented polynomial looks like.


Adding two polynomials that are represented by a linked list. We check values at the exponent
value of the node. For the same values of exponent, we will add the coefficients.
Example,
Input:
p1= 13x8 + 7x5 + 32x2 + 54
p2= 3x12 + 17x5 + 3x3 + 98
Output: 3x12 + 13x8 + 24x5 + 3x3 + 32x2 + 152
Explanation − for all power, we will check for the coefficients of the exponents that have the
same value of exponents and add them. The return the final polynomial.
Addition:
Same with subtraction & multiplication
Assignment 1 (CO 1)

SUBJECT NAME (CODE):- DS (KCS-301) CLASS: - B.TECH.(III SEM-B)


GIVEN DATE: 01/10/2022 SUBMISSION DATE: 10/10/2022

1. What do you understand by time and space trade-off? Define various asymptotic notations. Explain
best, worst, average analysis with example. [KL-3]
2. Suppose a multidimensional array P and Q are declared as P(-2:2, 2:22) and Q (1:8, -5:5, -10:5) stored
in column major order [KL-2]
i) Find the length of each dimension of P and Q
ii) The number of elements in P and Q.
iii) Assuming base address (Q) = 400, W= 4, Find the effective indices E1, E2, E3 and address of the
element Q[3,3,3].
3. Define singly linked list? Write a C program to insert a node at kth position in single linked list.[KL-3]
4. What is doubly linked list? Write down its applications. Explain how an element can be deleted from
doubly linked list using C program. [KL-3]
5. Discuss the representation of polynomial of single variable using linked list. Write 'C' functions to
add two such polynomials represented by linked list. [KL-3]

University Questions based on Unit - (I)


Sub. Code: - KCS-301 Sub. Name- Data Structure

DEC-2017
1. Define the term Data Structure. List some linear and non-linear data structures stating the application
area where they will be used. 2
2. What do you understand by time space trade off? Explain best, worst and average case analysis in this
respect with an example. 3
3. Define sparse matrix with its applications. Also explain how you can represent sparse matrix in
memory. 5
4. What are the various asymptotic notations? Explain Big O notation 7
5. Write an algorithm to insert a node at the end in a Circular linked list. 7
DEC-2018
1. Differentiate between overflow and underflow condition in linked list. 2
2. What do you understand by time and space trade-off? Define various asymptotic notations. Derive the
O-notation for linear search. 3
3. Write a program in C to delete a specific element in single linked list. Double linked list takes more
space than single linked list for storing one extra address. Under what condition, could a double
linked list more beneficial than single linked list. 7
4. Suppose a multidimensional array P and Q are declared as P(-2:2, 2:22) and Q (1:8, -5:5, -10:5)
stored in column major order 7
i) Find the length of each dimension of P and Q
ii) The number of elements in P and Q.
iii) Assuming base address (Q) = 400, W= 4, Find the effective indices E1, E2, E3 and address of the
element Q[3,3,3].
DEC-2019
1. List the various operations of linked list. 2
2. What are the merits and demerits of array? Give two arrays of integers in ascending order, develop an
algorithm to merge these arrays to form a third array sorted in ascending order. 10
3. What is doubly linked list? Write down its applications. Explain how an element can be deleted from
doubly linked list using C program. 10
DEC-2020
1. Define time space trade off. 2
2. Differentiate Array and Linked list. 2
3. Consider a multi-dimensional Array A[90] [30] [40] with base address starts at 1000. Calculate the
address of A[10] [20] [30] in row major order and column major order. Assume the first element is
stored at A[2][2][2] and each element take 2 byte. 10
4. Consider the two dimensional lower triangular matrix (LTM) of order N ,Obtain the formula for address
calculation in the address of row major and column major order for location LTM[j][k], if base address is
BA and space occupied by each element is w byte. 10
th
5. Write a C program to insert a node at k position in single linked list. 10

DEC-2021
1. Rank the following typical bounds in increasing order of growth rate: O(log n), O(n4 ), O(1), O(n2 log n)
2
2. List the advantages of doubly linked list over single linked list. 2
3. Write advantages and disadvantages of linked list over arrays. Write a 'C' function creating new linear
linked list by selecting alternate elements of a linear linked list. 10
4. Suppose a three dimensional array A is declared using A[1:10, -5:5, -10:5) (i) Find the length of each
dimension and the number of elements in A (ii) Explain Row major order and Column Major Order in
detail with explanation formula expression. 10
5. Discuss the representation of polynomial of single variable using linked list. Write 'C' functions to add
two such polynomials represented by linked list. 10

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy