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

Data Structures Notes

Uploaded by

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

Data Structures Notes

Uploaded by

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

Data Structures

What is Data Structure?

 A data structure is a storage that is used to store and organize data. It is a


way of arranging data on a computer so that it can be accessed and updated
efficiently.
 A data structure is not only used for organizing the data. It is also used for
processing, retrieving, and storing data.
 The data structure is not any programming language like C, C++, java, etc. It
is a set of algorithms that we can use in any programming language to
structure the data in the memory.

Types of Data Structures

There are two types of data structures:

1.Primitive data structure

Pooja Bhadauriya Page 1


2.Non-primitive data structure

1.Primitive Data structure

 The primitive data structures are primitive data types. The int, char, float,
double, and pointer are the primitive data structures that can hold a single
value.

2.Non-primitive data structure

 Non-Primitive Data Structures are those data structures derived from


Primitive Data Structures
 These data structures can't be manipulated or operated directly by machine-
level instructions.

 The focus of these data structures is on forming a set of data elements that is
either homogeneous (same data type) or heterogeneous (different data types).

The non-primitive data structure is divided into two types:

1.Linear data structure

2.Non-linear data structure

1.Linear data structure

he arrangement of data in a sequential manner is known as a linear data structure.


The data structures used for this purpose are Arrays, Linked list, Stacks, and
Queues. In these data structures, one element is connected to only one another
element in a linear form.

Data structures can also be classified as:

Static data structure: It is a type of data structure where the size is allocated at
the compile time. Therefore, the maximum size is fixed.

Dynamic data structure: It is a type of data structure where the size is allocated at
the run time. Therefore, the maximum size is flexible.

Advantages of Data structures

Pooja Bhadauriya Page 2


The following are the advantages of a data structure:

Efficiency: If the choice of a data structure for implementing a particular ADT is


proper, it makes the program very efficient in terms of time and space.

Reusability: The data structure provides reusability means that multiple client
programs can use the data structure.

Abstraction: The data structure specified by an ADT also provides the level of
abstraction. The client cannot see the internal working of the data structure, so it
does not have to worry about the implementation part. The client can only see the
interface.

What is an Algorithm?

 An algorithm is a process or a set of rules required to perform calculations or


some other problem-solving operations especially by a computer. The
formal definition of an algorithm is that it contains the finite set of
instructions which are being carried in a specific order to perform the
specific task.
 It is not the complete program or code; it is just a solution (logic) of a
problem, which can be represented either as an informal description using a
Flowchart or Pseudocode.

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.

Pooja Bhadauriya Page 3


Time complexity: The time complexity of an algorithm is the amount of time
required to complete the execution. The time complexity of an algorithm is
denoted by the big O notation. Here, big O notation is the asymptotic notation to
represent the time complexity. The time complexity is mainly calculated by
counting the number of steps to finish the execution. Let's understand the time
complexity through an example.

Space complexity: An algorithm's space complexity is the amount of space


required to solve a problem and produce an output. Similar to the time complexity,
space complexity is also expressed in big O notation.

Asymptotic Notations

The commonly used asymptotic notations used for calculating the running time
complexity of an algorithm is given below:

Big oh Notation (O)

Omega Notation (Ω)

Theta Notation (θ)

Big oh Notation (O)

 Big O notation is an asymptotic notation that measures the performance of


an algorithm by simply providing the order of growth of the function.
 This notation provides an upper bound on a function which ensures that the
function never grows faster than the upper bound. So, it gives the least upper
bound on a function so that the function never grows faster than this upper
bound.

Itis the formal way to express the upper boundary of an algorithm running time.
It measures the worst case of time complexity or the algorithm's longest amount
of time to complete its operation. It is represented as shown below:

Pooja Bhadauriya Page 4


For example:

If f(n) and g(n) are the two functions defined for positive integers,

then f(n) = O(g(n)) as f(n) is big oh of g(n) or f(n) is on the order of g(n)) if there exists
constants c and no such that:

f(n)≤c.g(n) for all n≥no

Example 1: f(n)=2n+3 , g(n)=n

Now, we have to find Is f(n)=O(g(n))?

To check f(n)=O(g(n)), it must satisfy the given condition:

f(n)<=c.g(n)

First, we will replace f(n) by 2n+3 and g(n) by n.

2n+3 <= c.n

Let's assume c=5, n=1 then

2*1+3<=5*1

5<=5

For n=1, the above condition is true.

Pooja Bhadauriya Page 5


If n=2

2*2+3<=5*2

7<=10

For n=2, the above condition is true.

We know that for any value of n, it will satisfy the above condition, i.e.,
2n+3<=c.n. If the value of c is equal to 5, then it will satisfy the condition
2n+3<=c.n. We can take any value of n starting from 1, it will always satisfy.
Therefore, we can say that for some constants c and for some constants n0, it will
always satisfy 2n+3<=c.n. As it is satisfying the above condition, so f(n) is big oh
of g(n) or we can say that f(n) grows linearly. Therefore, it concludes that c.g(n) is
the upper bound of the f(n). It can be represented graphically as:

Pooja Bhadauriya Page 6


Omega Notation (Ω)

 It basically describes the best-case scenario which is opposite to the big o


notation.
 It is the formal way to represent the lower bound of an algorithm's running
time. It measures the best amount of time an algorithm can possibly take to
complete or the best-case time complexity
 It determines what is the fastest time that an algorithm can run.

If we required that an algorithm takes at least certain amount of time without


using an upper bound, we use big- Ω notation i.e. the Greek letter "omega". It is
used to bound the growth of running time for large input size.

If f(n) and g(n) are the two functions defined for positive integers,

then f(n) = Ω (g(n)) as f(n) is Omega of g(n) or f(n) is on the order of g(n)) if
there exists constants c and no such that:

f(n)>=c.g(n) for all n≥no and c>0

Let's consider a simple example.

If f(n) = 2n+3, g(n) = n,

Is f(n)= Ω (g(n))?

It must satisfy the condition:

f(n)>=c.g(n)

To check the above condition, we first replace f(n) by 2n+3 and g(n) by n.

2n+3>=c*n

Suppose c=1

Pooja Bhadauriya Page 7


2n+3>=n (This equation will be true for any value of n starting from 1).

Therefore, it is proved that g(n) is big omega of 2n+3 function.

Theta Notation (θ)

The theta notation mainly describes the average case scenarios.

It represents the realistic time complexity of an algorithm. Every time, an


algorithm does not perform worst or best, in real-world problems, algorithms
mainly fluctuate between the worst-case and best-case, and this gives us the
average case of the algorithm.

Big theta is mainly used when the value of worst-case and the best-case is same.

It is the formal way to express both the upper bound and lower bound of an
algorithm running time.

Let's understand the big theta notation mathematically:

Let f(n) and g(n) be the functions of n where n is the steps required to execute
the program then:

f(n)= θg(n)

The above condition is satisfied only if when

c1.g(n)<=f(n)<=c2.g(n)

where the function is bounded by two limits, i.e., upper and lower limit, and
f(n) comes in between. The condition f(n)= θg(n) will be true if and only if
c1.g(n) is less than or equal to f(n) and c2.g(n) is greater than or equal to f(n).
The graphical representation of theta notation is given below:

Pooja Bhadauriya Page 8


Let's consider the same example where
f(n)=2n+3
g(n)=n

As c1.g(n) should be less than f(n) so c1 has to be 1 whereas c2.g(n) should be


greater than f(n) so c2 is equal to 5. The c1.g(n) is the lower limit of the of the
f(n) while c2.g(n) is the upper limit of the f(n).

c1.g(n)<=f(n)<=c2.g(n)

Replace g(n) by n and f(n) by 2n+3

c1.n <=2n+3<=c2.n

if c1=1, c2=2, n=1

1*1 <=2*1+3 <=2*1

1 <= 5 <= 2 // for n=1, it satisfies the condition c1.g(n)<=f(n)<=c2.g(n)

If n=2

1*2<=2*2+3<=2*2

2<=7<=4 // for n=2, it satisfies the condition c1.g(n)<=f(n)<=c2.g(n)

Storage Representation of String


Generally three types of structures are used to store strings.

Fixed length structure: In a fixed-length structure, each line of print is viewed as


a record. All records have the same length.

Variable-length storage: Variable length strings can be stored in memory cells


either by using a marker like $$ or \0 to represent the end of the string or by listing
the length of the string as an additional element in a pointer array.

Pooja Bhadauriya Page 9


 Linked Storage: We use a linked list to store strings. It helps to easily delete,
change, and insert words, sentences even paragraphs in the text. A linked list is an
ordered sequence of nodes, where each node contains a link which has the address
of the next node in the list. Here each node is assigned one character or a fixed
number of characters.
Keyword in Context (KWIC) Indexing

Keyword in Context (KWIC) Indexing system is based on the principle that the
title of the document represents its contents. It is believed that the title of the
document is one line abstract of the document. The significant words in the title
indicate the subject of the document. a KWIC index makes an entry under each
significant word in the title, along with the remaining part of the title to keep the
context intact. The entries are derived using terms one by one as the lead term
along with the entire context for each entry.

Structure

Each entry in KWIC index consists of three parts

i) Keyword: Significant words of the title which serve as approach/access


teems.

ii) Context: The rest of the terms of the title provided along with the
keywords specifies the context fo the document.
iii) Identification or Location Code: A code (usually the social number of
the entry) which provides address of the document where its full
bibliographical details will be available.

In order to indicate the end of the title a “/” symbol is used. The
identification code is put on the extreme right to indicate the location of the
document.

(b) Indexing Process

KWIC indexing system consists of three steps

Step I: Keyword selection


Step II: Entry generation

Pooja Bhadauriya Page 10


Step III: Filing
Step I: First of all significant words or keywords are selected from the title. It is
done by omitting articles, prepositions, conjunctions and others non-significant
words or terms. The selection is done by the editor who marks the keywords.
When a computer is used for preparing an index, the selection is done by having
‘stop list’ of non-significant terms stored in it. A stop list consists of articles,
prepositions and certain other common words which would be stopped from
becoming the keywords. Another method of providing the correct terms f entries is
by human intervention at the input stage, wherein the editor indicates the key terms
which are then picked up by the computer.

Step II: After the selection of keywords, the computer moves the title laterally in
such a way that a significant word (keyword) for a particular entry always appears
either on the extreme left-hand side or in the center. The same thing can be
performed manually following the structure of KWIC to generate entries.

Step III: After all the index entries for a document are generated, each entry is filed
at its appropriate place in the alphabetical sequence.

Example: Classification of Books in a University Library (with identification code


1279)

Pooja Bhadauriya Page 11


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.

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

Index starts with 0.

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

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

Memory allocation of an 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.

Pooja Bhadauriya Page 12


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

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

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

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

2D Array

2D array can be defined as an array of arrays. The 2D array is organized as


matrices which can be represented as the collection of rows and columns.

How to declare 2D Array

The syntax of declaring two dimensional array is very much similar to that of a one
dimensional array, given as follows.

1. int arr[max_rows][max_columns];

however, It produces the data structure which looks like following.

Pooja Bhadauriya Page 13


Stack
A Stack is a linear data structure that follows the LIFO (Last-In-First-Out)
principle. Stack has one end, whereas the Queue has two ends (front and rear). It
contains only one pointer top pointer pointing to the topmost element of the stack.
Whenever an element is added in the stack, it is added on the top of the stack, and
the element can be deleted only from the stack. In other words, a stack can be
defined as a container in which insertion and deletion can be done from the one
end known as the top of the stack

Standard Stack Operations


The following are some common operations implemented on the stack:

 push(): When we insert an element in a stack then the operation is known as


a push. If the stack is full then the overflow condition occurs.

Pooja Bhadauriya Page 14


 pop(): When we delete an element from the stack, the operation is known as
a pop. If the stack is empty means that no element exists in the stack, this
state is known as an underflow state.
 isEmpty(): It determines whether the stack is empty or not.
 isFull(): It determines whether the stack is full or not.
 peek(): It returns the element at the given position.

PUSH operation

The steps involved in the PUSH operation is given below:

 Before inserting an element in a stack, we check whether the stack is full.


 If we try to insert the element in a stack, and the stack is full, then
the overflow condition occurs.
 When we initialize a stack, we set the value of top as -1 to check that the stack is
empty.
 When the new element is pushed in a stack, first, the value of the top gets
incremented, i.e., top=top+1, and the element will be placed at the new position
of the top.
 The elements will be inserted until we reach the max size of the stack.

Pooja Bhadauriya Page 15


Algorithm for push item in stack

1 If TOP = Max-1

the stack is full.

2 If the stack is full, produces an error and exit.

3 If the stack is not full, increments top to point next empty space.

Set TOP= TOP + 1

4 Adds data element to the stack location, where top is pointing.

5 Returns success

Pooja Bhadauriya Page 16


POP operation

The steps involved in the POP operation is given below:

 Before deleting the element from the stack, we check whether the stack
is empty.
 If we try to delete the element from the empty stack, then
the underflow condition occurs.
 If the stack is not empty, we first access the element which is pointed by
the top
 Once the pop operation is performed, the top is decremented by 1,
i.e., top=top-1.

Pooja Bhadauriya Page 17


Algorithm
1 Checks If TOP= NULL stack is underflow.

2 If the stack is empty, produces an error and exit.

3 If the stack is not empty, accesses the data element at which top is pointing.

4 Decreases the value of top by 1

Set TOP= TOP-1

5 Returns success.

Peek()
The Peek operation is employed when it is necessary to return the value of the
topmost stack element without erasing it. This operation first determines whether
the Stack is empty, i.e., TOP = NULL; if it is, then the value will be returned;
otherwise, an appropriate notice will be displayed.

Algorithm
1.START

2. return the element at the top of the stack

3. END

isFull()
isFull() operation checks whether the stack is full. This operation is used to check
the status of the stack with the help of top pointer.
isEmpty()
The isEmpty() operation verifies whether the stack is empty. This operation is used
to check the status of the stack with the help of top pointer.

Pooja Bhadauriya Page 18


Application of Stack
1.Balancing of symbols

each program has an opening and closing braces; when the opening
braces come, we push the braces in a stack, and when the closing braces
appear, we pop the opening braces from the stack. Therefore, the net
value comes out to be zero. If any symbol is left in the stack, it means
that some syntax occurs in a program.
2.Recursion

The recursion means that the function is calling itself again. To maintain
the previous states, the compiler creates a system stack in which all the
previous records of the function are maintained .

3.Memory management

The stack manages the memory. The memory is assigned in the


contiguous memory blocks. The memory is known as stack memory as
all the variables are assigned in a function call stack memory. The
memory size assigned to the program is known to the compiler. When
the function is created, all its variables are assigned in the stack memory.
When the function completed its execution, all the variables assigned in
the stack are released.

4.Function call

In programs that call multiple functions in quick succession, the stack is


crucial. Assume we have a program with three A, B, and C functions.
Function A calls Function B, and Function B calls Function C.

Pooja Bhadauriya Page 19


Function A’s processing won’t be finished until function B’s execution
and return have been completed. This is because function A contains a
call to function B. The same is true of functions B and C. As a result, we
see that function A can only be finished after function B, and function B
can only be finished after function C. As a result, function A should be
begun first and finished last. In conclusion, utilising Stack makes it
simple to handle the function activity described above, which follows
the last in first out behaviour.
Consider the addresses of the statements to which control is transferred
following the completion of functions A, B, and C as addrA, addrB, and
addrC, respectively.

In the Stack, return addresses are displayed in the order that the
functions were called, as can be seen in the image above. Each function
is finished, followed by the pop operation, which starts execution at the
position where the Stack was removed.

Pooja Bhadauriya Page 20


Notation

 The way to write arithmetic expression is known as a notation. An


arithmetic expression can be written in three different but
equivalent notations, i.e., without changing the essence or output
of an expression. These notations are –
 Infix Notation
 Prefix (Polish) Notation
 Postfix (Reverse-Polish) Notation

Infix Notation
We write expression in infix notation, e.g. a - b + c, where operators are used in-
between operands. It is easy for us humans to read, write, and speak in infix
notation but the same does not go well with computing devices. An algorithm to
process infix notation could be difficult and costly in terms of time and space
consumption.

Prefix Notation
In this notation, operator is prefixed to operands, i.e. operator is written ahead of
operands. For example, +ab. This is equivalent to its infix notation a + b. Prefix
notation is also known as Polish Notation.

Postfix Notation
This notation style is known as Reversed Polish Notation. In this notation style, the
operator is postfixed to the operands i.e., the operator is written after the operands.
For example, ab+. This is equivalent to its infix notation a + b.

Pooja Bhadauriya Page 21


Airthmetic Expression conversion: Stack can also be used for
‘;expression conversion. This is one of the most important applications
of stack. The list of the expression conversion is given below:
Infix to prefix
Infix to postfix
Prefix to infix
Prefix to postfix
Postfix to infix

Infix to prefix

Conversion of Infix to Prefix using Stack


K + L - M * N + (O^P) * W/U/V * T + Q
If we are converting the expression from infix to prefix, we need first to reverse the
expression.

The Reverse expression would be:

Q + T * V/U/W * ) P^O(+ N*M - L + K

Pooja Bhadauriya Page 22


Input expression Stack Prefix expression

Q Q

+ + Q

T + QT

* +* QT

V +* QTV

/ +*/ QTV

U +*/ QTVU

/ +*// QTVU

W +*// QTVUW

* +*//* QTVUW

) +*//*) QTVUW

P +*//*) QTVUWP

^ +*//*)^ QTVUWP

O +*//*)^ QTVUWPO

( +*//* QTVUWPO^

+ ++ QTVUWPO^*//*

N ++ QTVUWPO^*//*N

* ++* QTVUWPO^*//*N

M ++* QTVUWPO^*//*NM

- ++- QTVUWPO^*//*NM*

L ++- QTVUWPO^*//*NM*L

Pooja Bhadauriya Page 23


+ ++-+ QTVUWPO^*//*NM*L

K ++-+ QTVUWPO^*//*NM*LK

QTVUWPO^*//*NM*LK+-++

The above expression, i.e., QTVUWPO^*//*NM*LK+-++, is not a final expression. We need to


reverse this expression to obtain the prefix expression.

Infix expression: K + L - M*N + (O^P) * W/U/V * T + Q

Input Expression Stack Postfix Expression

K K

+ +

L + KL

- - K L+

M - K L+ M

* -* K L+ M

N -* KL+MN

+ + K L + M N*
K L + M N* -

( +( K L + M N *-

O +( KL+MN*-O

^ +(^ K L + M N* - O

P +(^ K L + M N* - O P

) + K L + M N* - O P ^

* +* K L + M N* - O P ^

Pooja Bhadauriya Page 24


W +* K L + M N* - O P ^ W

/ +/ K L + M N* - O P ^ W *

U +/ K L + M N* - O P ^W*U

/ +/ K L + M N* - O P ^W*U/

V +/ KL + MN*-OP^W*U/V

* +* KL+MN*-OP^W*U/V/

T +* KL+MN*-OP^W*U/V/T

+ + KL+MN*-OP^W*U/V/T*
KL+MN*-OP^W*U/V/T*+

Q + KL+MN*-OP^W*U/V/T*Q

KL+MN*-OP^W*U/V/T*+Q+

The final postfix expression of infix expression(K + L - M*N + (O^P) * W/U/V * T + Q) is


KL+MN*-OP^W*U/V/T*+Q+.

Pooja Bhadauriya Page 25

You might also like