Decap267 Data Structures
Decap267 Data Structures
DECAP267
Edited by
Balraj Singh
Data Structures
Edited By:
Balraj Singh
CONTENT
Unit 4: Arrays 53
Dr. Prikshat Kumar Angra, Lovely Professional University
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 01: Basic Concepts
Objectives
After studying this unit, you will be able to:
Introduction
Data is any numerical or other information that is represented in a way that can be processed by a
computer. The way elements are placed or put together to make a whole is referred to as structure.
A data structure is the combination of data and all possible operations that must be performed on
that piece of data. Bits, characters, and integers are the most basic data types. Data structures are
used to manipulate and assemble information. However, the data available is usually in the
amorphous form. When different types of such amorphous data are related to each other, we refer
to it as a data structure.
Data Structures
A data structure can be described as a set of domains d, a set of functions F and a set of rules A.
D = {d, F, A}
Where,
D refers to Data structure
d refers to Domain variable
F refers to a set of functions or procedures operating on domain variables.
A is a set of rules governing the operations of these functions on the domain variable.
The instructions of a computer program use data to perform certain tasks. Some programs generate
data without using any inputs. Some programs generate data using a set of inputs, while some
programs use a data set to manipulate the given data. Thus, the data is processed efficiently only by
organizing them in a particular structure.
The study of data structures helps to understand the basic concepts involved in organizing and
storing data as well as the relationship among the data sets. This in turn helps to determine the way
information is stored, retrieved and modified in a computer’s memory. The study of data structures
is not limited to the study of data sets. It further extends to the study of representation of data
elements. This means that it explains how different types of data are placed in the computer's
memory using the binary number system, which forms the storage structure or memory
representation. Data structure is implemented in computer programs to manage data. The data is
managed using certain logical or mathematical models or concepts. A complex data structure can
also be built using simple data structures.
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. To structure the
data in memory, 'n' number of algorithms were proposed, and all these algorithms are known as
Abstract data types. These abstract data types are the set of rules.
12 2 3 4 85
0 1 2 3 4 (Index)
Data Structures
Example: A house can be identified by the house name, location, number of floors and so on.
These structured set of variables depend on each other to identify the exact house. Similarly, data
structure is a structured set of variables that are linked to each other, which forms the basic
component of a system.
Data Structures
correct data structure to write more efficient programs. This helps to solve the complexity of the
problems at a rapid rate.
In computer science, an algorithm is defined as a finite list of distinct instructions for calculating a
function. Algorithms are used for data processing, calculation and automated reasoning. An
algorithm can also be defined as a set of rules that accurately defines a series of operations.
Example: Instructions for assembling a puzzle can be an example of an algorithm. If you are
given a preliminary set of marked pieces, you can follow the instructions given to complete the
puzzle.
According to Levitin, algorithms can be defined as, “A sequence of unambiguous instructions for
solving a problem, i.e., for obtaining a required output for any legitimate input in a finite amount of
time.”
Most computer programs involve an algorithm and one or more data structures. An appropriate
data structure needs to be selected for an algorithm as the efficiency of the algorithm depends on
the data structure chosen. By increasing the data storage space, you may not be able to reduce the
time needed for processing the data and vice versa.
Example: When we want to print a mailing list alphabetically we need to use a data structure
and an algorithm. We first arrange all the names in a data structure (array) and then sort the names
alphabetically using an algorithm (sorting).
Example:
Int x
Float y
Where x and y are variable name and int and float are data types
Integer Data Type
An integer data type includes only whole numbers. It does not contain any fractional data. It is
denoted by the keyword int. It occupies 2 bytes of memory space. Integer data type can either be
signed or unsigned. The signed type integer takes both positive and negative values. The range of
integer constant is from -32768 to +32767 (-2^15 to +2^15 - 1) for a 16-bit compiler and -128 to 127 (-
2^7 to +2^7 - 1) for an 8-bit complier. A 16-bit compiler uses one bit for storing sign and the
remaining 15-bits for storing numbers. An 8-bit complier uses one bit for storing sign and the
remaining 7-bits for storing numbers. The unsigned integer ranges from 0 to 65535. The signed and
unsigned integers are specified as follows:
Syntax:
Unsigned int value;
Signed int value;
Example: -
Int x;
Scanf(“%d”,&x);
Printf(“%d”,x);
Where scanf() function is used for input data and printf() is used for print output on console screen.
Generally, there are three classes of integers namely, short int, int and long int. As shown in table,
short integers occupy only 1 byte, int occupies 2 bytes and the long integers occupy 4 bytes of
memory. Long integers can store longer range of values when compared to integer and short
integer.
Example: -
float x;
Scanf(“%f”,&x);
Printf(“%f”,x);
Where scanf() function is used for input data and printf() is used for print output on console screen.
As shown in table, float occupies 4 bytes of memory space. Double has longer precision than float
and occupies 8 bytes of memory space. The long double further extends the precision and occupies
10 bytes of memory space.
Example: -
char x;
Scanf(“%c”,&x);
Printf(“%c”,x);
Where scanf() function is used for input data and printf() is used for print output on console screen.
Following table gives the syntax and examples of the different data types.
Data Structures
Pointers
A pointer is a reference data structure. A pointer is actually a variable that stores the address of
another variable or structure in a program. The pointer variable holds only the memory location
and not the actual content. The pointer normally uses the address operator represented by ‘&’ and
the indirection operator represented by ‘*’. The address operator provides the address of the
variable and the indirection operator provides the value of the variable which is being pointed by
the pointer variable.
Note
There are different ways to organize data, for which there is a need for different kinds of data
structure.
1.9 Correctness
Data structure is designed such that it operates correctly for all kinds of input, which is based on
the domain of interest. In other words, correctness forms the primary goal of data structure, which
always depends on the specific problems that the data structure is intended to solve.
Example: A data structure designed to store a collection of numbers, in a specific order, must
make sure that the numbers are not stored in a haphazard way.
1.10 Efficiency
Data structure also needs to be efficient. It should process the data at high speed without utilizing
much of the computer resources such as memory space. In a real time state, the efficiency of a data
structure is an important factor that determines the success and failure of the process.
Example: NASA space shuttle requires a high level data structure design, so that it reacts
quickly to any changing conditions during a lift-off.
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.
Algorithms
Informally, an algorithm is any well-defined computational procedure that takes some value, or set
of values, as input and produces some value, or set of values, as output. An algorithm is thus a
sequence of computational steps that transform the input into the output.
We can also view an algorithm as a tool for solving a well-specified computational problem. The
statement of the problem specifies in general terms the desired input/output relationship. The
algorithm describes a specific computational procedure for achieving that input/output
relationship.
For example, we might need to sort a sequence of numbers into non decreasing order. This problem
arises frequently in practice and provides fertile ground for introducing many standard design
techniques and analysis tools. Here is how we formally define the sorting problem:
Input: A sequence of n numbers (a1; a2; ……; an),
Output: A permutation (reordering) (a’1, a’2,….,a’n ) of the input sequence such that a’1<a’2 <…. <a’n
Example: Given the input sequence h31; 41; 59; 26; 41; 58i, a sorting algorithm returns as
output the sequence h26; 31; 41; 41; 58; 59i. Such an input sequence is called an instance of the
sorting problem. In general, an instance of a problem consists of the input (satisfying whatever
constraints are imposed in the problem statement) needed to compute a solution to the problem.
Because many programs use it as an intermediate step, sorting is a fundamental operation in
computer science. As a result, we have a large number of good sorting algorithms at our disposal.
Which algorithm is best for a given application depends on—among other factors—the number of
items to be sorted, the extent to which the items are already somewhat sorted, possible restrictions
Data Structures
on the item values, the architecture of the computer, and the kind of storage devices to be used:
main memory, disks, or even tapes.
An algorithm can be specified in English, as a computer program, or even as a hardware design.
The only requirement is that the specification must provide a precise description of the
computational procedure to be followed.
Example: When you want to delete a record with a given key, you first need to use the search
operation to find the location of the record and then use the delete operation.
Summary
● Algorithms are used for data processing, calculations, and automated reasoning. An
algorithm can be defined as a set of rules that accurately define a series of operations.
● Algorithms are used for data processing, calculations, and automated reasoning. An
algorithm can be defined as a set of rules that accurately define a series of operations.
● Two fundamental goals of data structure are correctness and efficiency. Some of the
important features of data structures are robustness, adaptability and reusability.
● Data structure can be classified into two categories: primitive data structure and non-
primitive data structure.
● Basic data types such as integer, real, character, and Boolean are categorized under
primitive data structures. These data types are also known as simple data types because
they consist of characters that cannot be divided.
● Non-primitive data structures are further divided into linear and non-linear data structure
based on the structure and arrangement of data.
Data Structures
● An Abstract Data Type (ADT) is a technique that is used to specify the logical properties of
a data type. It can be considered as a basic mathematical concept used to define the data
types.
Keywords
Amorphous: Not having a definite form; shapeless.
Efficiency: Efficiency of a program depends upon the choice of data structures
Creation Operation: The creation operation creates a data structure.
Deletion: Deletion refers to removing an item from the structure.
Self Assessment
6. A procedure for solving a problem in terms of action and their order is called as
A. Process
B. Program instruction
C. Algorithm
D. Template
14. ____ can be defined as process of combining elements of two data structure
A. Insertion
B. Deletion
C. Sorting
D. Merging
Data Structures
6. C 7. C 8. A 9. A 10. C
Review Questions
1. Describe the types of Data Structures?
2. What do you mean by linear data structure?
3. How nonlinear data structure are different from linear data structure. Explain your
answer with suitable example.
4. What is an algorithm? Write an algorithm to check entered number is even or odd.
5. Explain data structure operations with suitable example.
6. What are the advantages of data structures?
7. Write good qualities of algorithm.
8. What is importance of an algorithm?
9. How linked list is different from array.
10. Give any real life example of data structure.
Further Readings
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Web Links
https://tutorialsinhand.com/tutorials/data-structure-tutorial/data-structure-
basics/introduction-to-data-structure.aspx
http://www.cplusplus.com/doc/tutorial/variables/
https://aofa.cs.princeton.edu/home/
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 02: Complexity of Algorithms
Objectives
After studying this unit, you will be able to:
Introduction
Each computer program is a series of instructions that are arranged in a specific order to perform a
specific task. A computer program is written to instruct a computer to perform a specific task in
order to obtain the desired result. Irrespective of the language used to develop a program, there are
some generic steps that can be followed to solve a problem. These generic steps are called
algorithms. According to H. Cormen, "Before there were computers, there were algorithms." An
algorithm is a set of instructions that performs a particular task. It is considered as a tool that helps
to solve a specific computational problem.
Mathematical notation is a system of symbolic representations of mathematical objects and ideas.
Mathematical functions appear quite often in the analysis of algorithm along with their notation.
Some of the mathematical functions are floor and ceiling functions, summation symbol, factorial,
Fibonacci numbers, and so on.
The complexity of an algorithm is a function that describes the efficiency of an algorithm in terms of
the amount of data the algorithm must process.
The two main complexity measures of efficiency of an algorithm are:
Data Structures
1. Time Complexity: It is a function that describes the time taken by an algorithm to solve a
problem.
2. Space Complexity: It is a function that describes the amount of memory or space required
by an algorithm to run. A good algorithm has minimum number of space complexity.
Algorithm analysis is an important part of computational complexity theory. It provides theoretical
estimates for the resources that are needed for any algorithm to solve a given problem. These
estimates provide an insight into the measures that determine algorithm efficiency. It is necessary
to check the efficiency of each of the algorithms in order to select the best algorithm. We can easily
measure the efficiency of algorithms by calculating their time complexity. The shorthand way to
represent time complexity is asymptotic notation. It is a function that describes the amount of
memory or space required by an algorithm to run. A good algorithm has minimum number of
space complexity.
Example: Consider the algorithm for sorting a deck of cards. This algorithm continues
repeatedly searching through the deck for the lowest card. The square of the number of cards in the
deck is the asymptotic complexity of this algorithm.
Asymptotic Notations
Asymptotic analysis of an algorithm refers to defining the mathematical boundation/framing of its
run-time performance. Using asymptotic analysis, we can very well conclude the best case, average
case, and worst case scenario of an algorithm.
A problem may have various algorithmic solutions. In order to choose the best algorithm for a
particular process, you must be able to judge the time taken to run a particular solution. More
accurately, you must be able to judge the time taken to run two solutions, and choose the better
among the two.
To select the best algorithm, it is necessary to check the efficiency of each algorithm. The efficiency
of each algorithm can be checked by computing its time complexity. The asymptotic notations help
to represent the time complexity in a shorthand way. It can generally be represented as the fastest
possible, slowest possible or average possible.
Asymptotic analysis is input bound i.e., if there's no input to the algorithm, it is concluded to work
in a constant time. Other than the "input" all other factors are considered constant.
Asymptotic analysis refers to computing the running time of any operation in mathematical units
of computation. For example, the running time of one operation is computed as f(n) and may be for
another operation it is computed as g(n2). This means the first operation running time will increase
linearly with the increase in n and the running time of the second operation will increase
exponentially when n increases. Similarly, the running time of both operations will be nearly the
same if n is significantly small.
Usually, the time required by an algorithm falls under three types −
Following are the commonly used asymptotic notations to calculate the running time complexity of
an algorithm.
Ο Notation
Ω Notation
θ Notation
Big-O Notation
‘O’ is the representation for Big-O notation. Big-O is the method used to express the upper bound of
the running time of an algorithm. It is used to describe the performance or time complexity of the
algorithm. Big-O specifically describes the worst-case scenario and can be used to describe the
execution time required or the space used by the algorithm.
Table gives some names and examples of the common orders used to describe functions. These
orders are ranked from top to bottom.
Big-O notation is generally used to express an ordering property among the functions. This
notation helps in calculating the maximum amount of time taken by an algorithm to compute a
problem. Big-is defined as:
f(n) ≤ c∗g(n)
where, n can be any number of inputs or outputs and f(n) as well as g(n) are two non-negativefunctions. These
functions are true only if there is a constant c and a non-negative integer n0≥such that,n n 0.
The notation Ο(n) is the formal way to express the upper bound of an algorithm's running time. It measures
the worst case time complexity or the longest amount of time an algorithm can possibly take to complete.
Data Structures
Omega Notation, Ω
The notation Ω(n) is the formal way to express the lower bound of an algorithm's running time. It
measures the best case time complexity or the best amount of time an algorithm can possibly take
to complete.
Ω(f(n)) ≥ { g(n) : there exists c > 0 and n0 such that g(n) ≤ c.f(n) for all n > n0. }
Omega Notation, Ω
The notation Ω(n) is the formal way to express the lower bound of an algorithm's running time. It
measures the best case time complexity or the best amount of time an algorithm can possibly take
to complete.
Ω(f(n)) ≥ { g(n) : there exists c > 0 and n0 such that g(n) ≤ c.f(n) for all n > n0. }
Theta Notation, θ
The notation θ(n) is the formal way to express both the lower bound and the upper bound of an
algorithm's running time. It is represented as follows –
θ(f(n)) = { g(n) if and only if g(n) = Ο(f(n)) and g(n) = Ω(f(n)) for all n > n0. }
2
quadratic -> Ο(n )
Data Structures
3
cubic -> Ο(n )
Ο(1)
polynomial -> n
Ο(n)
exponential -> 2
Example
Function f(x)=2x
In this case, the function is assigned to every real number, the real number with twice its value.
Assume x=5, then we can write f(5) = 10
Example
floor(1.01)=1
floor(0)=0
floor(2.9)=2
floor(-3)=-3
floor(-1.1)=-2
Find out floor(x) for various values of x
Ceiling function is represented as ceiling(x). It gives the smallest integer value greater than or equal
to x. The domain of ceiling(x) is the set of all real numbers. The range of ceiling(x) is the set of all
integers.
Let us consider the following example.
Example
ceiling (1.5)=2
ceiling(0)=0
ceiling(2)=2
ceiling(-3)=-3
ceiling(-1.1)=-1
Find out ceiling(x) for various values of x.
Summation Symbol
Summation symbol is Σ. Summation is the operation of combining a sequence of numbers using
addition. The result is the sum or total of all the numbers. Apart from numbers, other types of values
such as, vectors, matrices, polynomials, and elements of any additive group can also be added using
summation symbol.
Example: Consider a sequence x1, x2, x3……x10. The simple addition of this sequence
isx1+x2+x3+x4+x5+x6+x7+x8+x9+x10. Using mathematical notation we canshorten the addition. It can be
done by using a symbol to denote “all the way upto” or “all the way down to”.
Then, the expression will be x1+x2+x3+…..+x10. We can also represent theexpression using Greek letter Σ
as shown below:
Here, a is the first index and b is the last index. The variables are the numbers that appear
constantly in all terms. In the expression,
x1+x2+x3+x4+x5+x6+x7+x8+x9+x10
1 is the first index, 10 is the last index, and x is the variable. If we use i as the index variable then the
expression will be
Exponential function has the form f(x) =ax+B where, a is the base, x is the exponent, and B is any
expression.
If a is positive, the function continuously increases in value. As x increases, the slope of the function also
increases.
The graph for y=2x is shown in figure. In the graph as x increases, y also increases, and as x
increases the slope of the graph also increases.
Data Structures
A logarithm is an exponent. The logarithmic function is defined as f(x)= logb x. Here, the base of
the algorithm is b. The two most common bases which we use are base 10 and base e
Example: Consider the exponential equation 52=25 where 5 is base and 2 is exponent.
The logarithmic form of this equation is:
Log525=2
Here, we can say that the logarithm of 25 to the base 5 is 2.
Factorial
The symbol of the factorial function is ‘!’. The factorial function multiplies a series of natural
numbers that are in descending order. The factorial of a positive integer n which is denoted by n!
represents the product of all the positive integers is less than or equal to n.
n!=n*(n-1)*(n-2)……2*1
Example
5!=5*4*63*2*1=120
Fibonacci Numbers
In the Fibonacci sequence, after the first two numbers i.e. 0 and 1 in the sequence, each subsequent
number in the series is equal to the sum of the previous two numbers. The sequence is named after
Leonardo of Pisa, also known as Fibonacci.
Fibonacci numbers are the elements of Fibonacci sequence:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765…….
Sometimes this sequence is given as 0, 1, 1, 2, 3, 5….. There are also other Fibonacci sequences
which start with the numbers:
3, 10, 13, 23, 36, 59…….
Fibonacci numbers are the example of patterns that have intrigued mathematicians through the
ages. In mathematical terms, the sequence Fn of Fibonacci numbers is defined as:
Fn= Fn-1+ Fn-2
Example: Beginning with a single pair of rabbits, if every month each productive pair
bears a new pair, who become productive when they are 1 month old, how many rabbits will there
be after n months?
Assume that there are xn pairs of rabbits after n months. The number of pairs in n+1 month is xn+1.
Each pair produces a new pair every month but no rabbit dies within that period. New pairs are
only born to pairs which are at least 1 month old, so there is an x n-1 new pair.
Xn+1 = xn + xn-1
Algorithmic Complexity
We can determine the efficiency of an algorithm by calculating its performance. Following are the
two factors that help us to determine the efficiency of an algorithm:
1. Time Complexity
2. Space Complexity
The amount of computer time required to solve a problem is the time complexity of an
algorithm and the amount of memory required to compute the problem is the space
complexity of an algorithm.
Time Complexity
Time complexity of an algorithm is the amount of time required by an algorithm to execute. It is
always measured using the frequency count of all important statements or the basic instructions.
This is because the clock limitation and multiprogramming environment makes it difficult to obtain
a reliable timing figure.
The time taken by an algorithm is the sum of compile time and run time. The compile time does not
depend on the instance characteristics, as a program once compiled can be run many times without
recompiling. Thus, only the run-time of the program matters while calculating time complexity. Let
us take an example to get a clear idea of how time complexity of an algorithm is computed.
Table shows analysis of time complexity
Data Structures
1. In step A, there is one independent statement ‘x= x+1’ and it is not within any loop.
Hence, this statement will be executed only once. Thus, the frequency count of step A of
the algorithm is 1.
2. In step B, there are three statements out of which ‘x = x+1’ is an important statement. As
the statement ‘x = x+1’ is contained within the loop, the statement will be executed n
number of times.
Thus, the frequency count of algorithm is n.
3. In step C, the inner and outer loop runs n number of times. Thus, the frequency count is
n2.
During the analysis of algorithm, the focus is on determining those statements that provide the
greatest frequency count. The formulas used to calculate the steps executed by an algorithm
are:
1 + 2 +……+ n = n(n+1)/2
12+22+…..+ n2 = n(n+1)(2n+1)/6
If an algorithm has input of size n and performs f(n) basic functions, then the time taken to
execute those functions will be cf(n), where c is a constant that depends upon the algorithm
design.
The time complexity of an algorithm can be further analyzed as best case, worst case and
average case time complexity.
1. In best case time complexity, an algorithm will take minimum amount of time to solve a
particular problem. In other words, the algorithm runs for a short time.
2. In worst case time complexity, an algorithm will take maximum amount of time to solve a
particular problem. In other words, algorithm runs for a long time.
3. In average case time complexity, only certain sets of inputs to the algorithm get the timecomplexity.
It specifies the behavior of an algorithm on a particular input.
Space Complexity
Space complexity is the amount of memory an algorithm requires to run. The space complexity of
an algorithm can be determined by relating the size of a problem (n) to the amount of memory (s)
needed to solve that problem. Thus, the space complexity can be computed by using the below two
components:
1. Fixed Space Requirement: It is the amount of space acquired by fixed sized structure,
variables, and constants.
2. Variable Space Requirement: It is the amount of space required by the structured
variables, whose size depends on particular problem instance.
Example
Algorithm: To compute the sum of three elements
//Input: x, y, and z are of integer type
Input x, y, z
//Output: The sum of three integers is returned
return x+y+z
Thus, if each of the input elements occupies 2 bytes of memory space,
then the inputs x, y, z will require a total memory size of 6 bytes.
In general, space complexity helps to define the amount of memory required to solve a particular
problem.
Data Structures
Best Case Analysis
If an algorithm takes the least amount of time to execute a specific set of input, then it is called the
best case time complexity. The best case efficiency of an algorithm is the efficiency for the best case
input of size n. Because of this input, the algorithm runs the fastest among all the possible inputs of
the same size.
To analyze the best case efficiency, we have to first determine the kind of inputs for which the
count C(n) will be the smallest among all possible inputs of size n. Then, we ascertain the value of
C(n) on the most convenient inputs.
Example: In case of sequential search, the best case for lists of size n is when their first
elements are equal to the search key. Then,
Cbest (n) = 1
Example: Assume that in case of sequential search, the probability of successful search is
equal to t i.e. 0 ≤ t ≤ 1, and the probability o f the first match occurring in the ith position of
the list is the same for all values of i. From these assumptions we can easily find out the average
number of key comparisons Cavg (n).
In case of successful search, the probability of the first match occurring in the ith position of the list
is t/n for all values of i and the comparison made by the algorithm is also i.
In case of unsuccessful search, the number of comparison is n with the probability of (1 - t) .
Therefore, we can write:
For t=1, the average number of key comparisons made by sequential search is (n + 1) / 2 which
means the algorithm inspects on an average about half of the list’s elements. For t=0, the average
number of key comparisons is n which means the algorithm inspects all n element on all such
inputs.
Example: In case of sequential search, if the search element key is present at the nth position
of the list, then the basic operations and time required to execute the algorithm is more. Thus, it
gives the worst case time complexity. Worst case time complexity is represented as:
Cworst(n)=n
1. Sequencing: - Suppose our algorithm is divided into two parts, A and B. A takes time tA
and B takes time tB for computation. The total computation “tA + tB" is according to the
sequence rule. According to the maximum rule, this computation time is (max (tA,tB)).
Example
Let
tA =O (n) and tB = θ (n2).
Then, the total computation time can be calculated as
Computation Time = tA + tB
= (max (tA ,tB))
= (max (O (n), θ (n2)) = θ (n2))
Data Structures
Example
• Suppose tA = O (n2) and tB = θ (n2)
• Calculate the total computation time for the following:
3. For loop: - For loop used when programmer need continuous execution of an algorithm in
specific time.
4. While loop:-The simple technique for analysing the loop is to determine the function of
the variable involved whose value decreases each time around. It is necessary that the
value must be a positive integer to terminate the loop.
Summary
A computer program is written as a sequence of steps that needs to be performed to obtain
the desired result.
Mathematical notation is a system of symbolic representations of mathematical objects and
ideas.
Some of the mathematical functions are floor and ceiling functions, summation symbol,
factorial, Fibonacci numbers, and so on.
The complexity of an algorithm is a function which describes the efficiency of an algorithm
in terms of the amount of data the algorithm must process.
The efficiency of each algorithm can be checked by computing its time complexity.
The asymptotic notations help to represent the time complexity in a shorthand way. It can
generally be represented as fastest possible, slowest possible, or average possible.
The floor and ceiling functions give the nearest integer up or down.
In the Fibonacci sequence, after the first two numbers, i.e., 0 and 1 in the sequence, each
subsequent number in the series is equal to the sum of the previous two numbers.
Analysis of an algorithm is required to determine the amount of resources such as, time and
storage required to execute the algorithm.
Keywords
Lower Bound: A mathematical argument which means that you can't hope to go faster than a
certain amount.
Memory: An internal storage area in the computer.
Notation: The activity of representing something by a special system of characters.
Upper Bound: A number equal to or greater than any other number in a given set.
Self Assessment
4. Data space is
A. Amount of space used by the variables and data types
B. Amount of space used by the variables and constants
C. Amount of space used by the constants and data types
D. None of above
Data Structures
6. Which of the following are types of assumption notations.
A. Big Theta
B. Big Oh
C. Big Omega
D. All of above
7. Which of the following best describes the useful criterion for comparing the efficiency of
algorithms?
A. Time
B. Memory
C. Both of the above
D. None of the above
6. D 7. C 8. D 9. B 10. D
Review Questions
1. “Mathematical notation is a system of symbolic representations of mathematical objects
and ideas.” Discuss.
2. “To select the best algorithm, it is necessary to check the efficiency of each algorithm.”
Justify.
3. “Big-O notation describes the performance or time complexity of an algorithm.”
Comment.
4. “The omega notation can be defined as f(n)≥ c∗ g(n).” Describe.
5. “Floor function gives the largest integer lesser than or equal to x.” Describe with an
example.
6. Describe modular arithmetic with the help of a 12 hour clock.
7. “Efficiency of an algorithm can be determined by calculating its performance.”
Comment.
8. “Time complexity of an algorithm is the amount of time required by an algorithm to
execute.” Discuss with an example.
9. “Time space tradeoff in context of algorithms relates to the execution of an algorithm.”
Comment.
10. “Analysis of an algorithm is required to determine the amount of resources it requires.”
Discuss.
Further Readings
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Web Links
https://devopedia.org/algorithmic-
complexity#:~:text=Algorithmic%20complexity%20is%20a%20measure,for%20large%20val
ues%20of%20n.&text=Algorithmic%20complexity%20is%20also%20called%20complexity%
20or%20running%20time.
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 03: Introduction to Pointers
Objectives
After studying this unit, you will be able to:
Introduction
Computers use their memory for storing instructions of the programs as well as the values of the
variables. Since memory is a sequential collection of storage cells each cell has an address
Data Structures
associated with it. Whenever we declare a variable, the system allocates, somewhere in the
memory, a memory location and a unique address is assigned to this location. Whenever a value is
assigned to this variable the value gets stored in the location having a unique address in the
memory associated with that variable. Therefore, the values stored in memory can be manipulated
using their addresses. Pointer is an extremely powerful mechanism to write efficient programs.
Incidentally, this feature makes C stand out as the most powerful programming language. Pointers
are the topic of this unit.
3.1 Pointers
A memory variable is merely a symbolic reference given to a memory location. Now let us consider
that an expression in a C program is as follows:
int a = 10, b = 5, c;
c = a + b;
The above expression implies that a, b and c are the variables which can hold the integer data. Now
from the above mentioned statement let us assume that the variable ‘a’ occupies the address 3000 in
the memory, ‘b’ occupies 3020 and the variable ‘c’ occupies 3040 in the memory. Then the compiler
will generate the machine instruction to transfer the data from the location 3000 and 3020 into the
CPU, add them and transfer the result to the location 3040 referenced as c. Hence
we can conclude that every variable holds two values:
Address of the variable in the memory (l-value)
Value stored at that memory location referenced by the variable. (r-value)
Pointer is nothing but a simple data type in C programming language, which has a
specialcharacteristic to hold the address of some other memory location as its r-value. C
programminglanguage provides ‘&’ operator to extract the address of any object. These addresses
can be storedin the pointer variable and can be manipulated.
The syntax for declaring a pointer variable is,
<data type> *<identifier>;
Example
int n;
int *ptr; /* pointer to an integer*/
The following statement assigns the address location of the variable n to ptr, and ptr is a pointer to
n.
ptr=&n;
Since a pointer variable points to a location, the content of that location is obtained by prefixing the
pointer variable by the unary operator * (also called the indirection or dereferencing operator) like,
*<pointer_variable>.
Example:
# include<stdio.h>
main()
{
int a=10, *ptr;
ptr=&a; /* ptr points to the location of a */
printf(“The value of a pointed by the pointer ptr is: %d”, *ptr);
/* printing the value of a pointed by ptr through the pointer ptr*/
As the memory addresses are numbers, they can be assigned to some other variable. Let ptr be the
variable which holds the address of variable num. We can access the value of num by the variable
ptr. Thus, we can say “ptr points to num”. Diagrammatically, it can be shown as:
Data Structures
3.3 Pointer Declaration
Since pointer variables contain address that belongs to a separate data type, they must be declared
as pointers before we use them. Pointers can be declared just a any other variables. The declaration
of a pointer variable takes the following form:
data_type *pt_name;
The above statement tells the compiler three things about the variable pt_name.
1. The asterisk (*) tells that the variable pt_name is a pointer variable.
2. pt_name needs a memory location.
3. pt_name points to a variable of type data type.
Example:
main( )
{
int i = 3;
printf (“\n Address of i: = %u”, & i); /* returns the address * /
printf (“\t value i = %d”, * (&i)); /* returns the value of address of i */
}
Example: int *p; declares the variable p as a pointer variable that points to an integer data
type. The type int refers to the data type of the variable being pointed to by p and not the type of
the value of the pointer.
Once a pointer variable has been declared, it can be made to point to a variable using an assignment
statement such as p = &quantity; which causes p to point to quantity. That is, p now contains the
address of quantity. This is known as pointer initialization. Before a pointer is initialized, it should
not be used. A pointer variable can be initialized in its declaration itself.
Data Structures
Example: int x, *p=&x; statement declares x as an integer variable and p as a pointer variable
and then initializes p to the address of x. This is an initialization of p, not *p. On the contrary, the
statement int *p = &x, x; is invalid because the target variable x is declared first.
Example:
Program to illustrate pointer increment/decrement
#include <stdio.h>
// Driver Code
int main()
{
// Integer variable
int N = 4;
// Pointer to an integer
int *ptr1, *ptr2;
// Pointer stores
// the address of N
ptr1 = &N;
ptr2 = &N;
Data Structures
ptr1--;
return 0;
}
Pointer Comparisons
Pointers may be compared by using relational operators, such as ==, <, and >. If p1 and p2 point to
variables that are related to each other, such as elements of the same array, then p1 and p2 can be
meaningfully compared.
The following program modifies the previous example − one by incrementing the variable pointer
so long as the address to which it points is either less than or equal to the address of the last
element of the array, which is &var[MAX - 1]
Data Structures
int main () {
return 0;
}
Lab Exercise
// Program to demonstrate working of Pointers
#include<stdio.h>
int main(){
int n=123;
int *ptr=&n;
int **nn=n;
//*ptr=&n;
printf("Original value of variable n is = %d\n",n);
printf("Address of n is = %p\n",ptr);
printf("Address of n in decimal number is = %d\n",ptr);
printf("Value of %d",nn);
return 0;
}
Lab Exercise
// Program to access value using Pointers
#include<stdio.h>
int main(){
int x;
printf("Enter Value of x\n");
scanf("%d",&x);
int *p;
p=&x;
printf("value of x entered by user is %d\n",x);
printf("Address of variable x is %p\n",p);
printf("Getting value from pointer variable %d\n",*p);
printf("Address of variable x is %d\n",p);
printf("Address of variable x is %u\n",p);
*p=500;
printf("New value of x is %d\n",x);
return 0;
Lab Exercise
// Program for Pointer Arithmatics
#include<stdio.h>
int main(){
int a,b,sum,sub,mul,div;
int *ptr1,*ptr2;
printf("Enter first number");
scanf("%d",&a);
printf("Enter second number");
scanf("%d",&b);
ptr1=&a;
Data Structures
ptr2=&b;
sum=*ptr1+*ptr2;
sub=*ptr1-*ptr2;
mul=*ptr1* *ptr2;
div= *ptr1/ *ptr2;
printf("Using pointers, all arithmetic operations
performed\n");
printf("Sum of first and second number is =%d\n",sum);
printf("Subtraction of first and second number is %d\n",sub);
printf("Product of first and second number is %d\n",mul);
printf("Division of first and second number is %d\n",div);
printf("Address of first and second number a=%p, b=%p
",ptr1,ptr2);
return 0;
}
Example:
#include<stdio.h>
int main(){
int *ptr;
ptr=NULL;
printf("Value of null pointer is %d",ptr);
return 0;
}
Data Structures
Example:
#include <stdio.h>
typedef struct
{
char *name;
int acct_no;
char accttype;
float balance;
}
record;
/* transfer a structure-type pointer to a function */
main( )
{
void adjust (record *pt); /* function declaration * /
static record customer = {“Smith”, 3333, ‘C’, 33.33};
printf (“%s %d %c %.2f\n”, customer.name, customer.acct_no,
customer.acct_type, customer.balance);
adjust (&customer);
printf (“%s %d %c %.2f\n”, customer.name, customer.acct_no,
Data Structures
2. Arrow Operator
When the structure is referred to by its name, the structure elements are addressed using
dot
operators.
Example: b1.name
When the structure is referred to by the pointer to structure, the structure elements are
addressed
using arrow operators.
Example: ptr->name
On the left hand side of ‘.’ structure operator, there must always be a structure variable,
whereas on the right hand side of the ‘->’ operator there must always be a pointer to a
structure.
The following program demonstrates the passing of address of a structure variable to a
function.
struct emp
{
char empname [25];
int empno;
}
main( )
{
static struct emp emp1 = {Prashant”,”socem”, 101};
display (&emp1);
}
display (e)
struct emp *e; /*pointer to a structure */
{
printf (“%s \n%s\n%d”, e->empname, e->empno);
}
Output: Prashant
SOCEM
101
In the above example, -> operator is used to access the structure elements using pointer to
structure.
struct name {
member 1;
The above illustrated structure prototype describes one node that comprises of two logical
segments. One of them stores data/information and the other one is a pointer indicating where the
next component can be found. .Several such inter-connected nodes create a chain of structures.
The following figure depicts the composition of such a node. The figure is a simplified illustration
of nodes that collectively form a chain of structures or linked list.
Such self-referential structures are very useful in applications that involve linked data structures,
such as lists and trees. Unlike a static data structure such as array where the number of elements
that can be inserted in the array is limited by the size of the array, a self-referential structure can
dynamically be expanded or contracted. Operations like insertion or deletion of nodes in a self-
referential structure involve simple and straight forward alteration of pointers.
Example
#include<stdio.h>
struct data{
int a;
char c;
struct data *ptr;
};
int main(){
struct data data1;
struct data data2;
data1.a=100;
data1.c='A';
data1.ptr=NULL;
data2.a=200;
data2.c='B';
data2.ptr=NULL;
data1.ptr=&data2;
printf("Value of data 1 direct from structure %d %c \n",data1.a,data1.c);
printf("Values of data1 reference to the data2 %d %c", data1.ptr->a,data1.ptr->c);
return 0;
}
Data Structures
Summary
Pointers are often passed to a function as arguments by reference. This allows data items
within the calling function to be accessed, altered by the called function, and then returned
to the calling function in the altered form.
There is an intimate relationship between pointers and arrays as an array name is really a
pointer to the first element in the array.
Access to the elements of array using pointers is enabled by adding the respective subscript
to the pointer value (i.e. address of zeroth element) and the expression preceded with an
indirection operator.
As pointer declaration does not allocate memory to store the objects it points at, therefore,
memory is allocated at run time known as dynamic memory allocation.
Self-referential structure are special structure that can hold links to the other structures.
Keywords
Array of Pointer: A multi-dimensional array can be expressed in terms of an array of pointers
rather than as a pointer to a group of contiguous arrays.
Pointer: It is a variable which can hold the address of a memory location rather than the value
at the location.
Pointer Expression: Like other variables, pointer variables can be used in expressions.
Arithmetic and comparison operations can be performed on the pointers
Self-Assessment
int main(){
int *ptr=NULL;
return 0;
A. 1
B. 2
C. 0
D. 4
A. 100
B. 80
C. 900
D. 10
Data Structures
11. What are the different operations that can be performed on pointers?
A. Decrement
B. Addition
C. Subtraction
D. Above all
6. C 7. C 8. D 9. C 10. B
Review Questions
1. Define ‘Pointer’. List down the various advantages of using pointers in a C program.
2. How pointer are initialized and implemented in C? Write a program to explain the concept.
3. Explain with the help of a C program, the concept of Pointer Arithmetic in C.
4. How printer in C incorporates the concept of Arrays? Write a suitable program to demonstrate
the concept.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson
Education, Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi
Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett,
1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web links
https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-
array/
https://www.careerride.com/C-self-referential-structure.aspx
Objectives
After studying this unit, you will be able to:
Explain arrays
Describe two dimensional array
Describe array initialization
Introduction
An array is a group of data items of same data type that share a common name. Ordinary variables
are capable of holding only one value at a time. If we want to store more than one value at a time in
a single variable, we use arrays.
An array is a collective name given to a group of similar quantities. Each member in the group is
referred to by its position in the group.
Arrays are allotted the memory in a strictly contiguous fashion. The simplest array is one
dimensional array which is simply a list of variables of same data type. An array of one-
dimensional arrays is called a two-dimension array.
4.1 Arrays
Arrays are allocated the memory in a strictly contiguous fashion. The simplest array is one
dimensional array which is a list of variables of same data type. An array of one dimensional arrays
is called a two dimensional array; array of two dimensional arrays is three dimensional array and
so on.
The members of the array can be accessed using positive integer values (indicating their order in
the array) called subscript or index. Look at an array of integers as shown below:
Data Structures
1. One-dimensional Array
A list of items can be given one variable name using only one subscript and such a variable is called
a one-dimensional array.
Example: If we want to store a set of five numbers by an array variable number. Then it will be
accomplished in the following way:
As C performs no bounds checking, care should be taken to ensure that the array indices are within
the declared limits. Also, indexing in C begins from 0 and not from 1.
This is a table of four rows and three columns. Such a table of items can be defined using two
dimensional arrays.
General form of declaring a 2-D array is
data_typearray_name [row_size] [colum_size];
Data Structures
int i, j; temp;
printf (“\n Enter the elements of the array:”};
scanf (“%d”, &arr [i]);
for (i = 0; i< = 4; i ++);
{
for (J = 0; J < = 3; J ++)
if (arr [J] >arr [J+1])
{
temp = arr [J];
arg [J] = arr [J+1];
arr [J+1] = temp;
}
}
printf (“\ n The Sorted array is:”);
for (i = 0; i< 5; i++)
printf (“\ t %d”, arr [i]);
}
Character Arrays
Just as a group of integers can be stored in an integer array, group of characters can be stored in a
character array or “strings”. The string constant is a one dimensional array of characters terminated
by null character (‘\0’). This null character ‘\0’ (ASCII value0) is different from ‘O’
(ASCII value 48).
The terminating null character is important because it is the only way the function that works with
string can know where the string ends.
Example: Static char name [ ] = {‘K’, ‘R’, ‘I’, ‘S’, ‘H’, ‘\0’};
This example shows the declaration and initialization of a character array. The array elements of a
character array are stored in contiguous locations with each element occupying one byte of
memory.
Notes
1. Contrary to the numeric array where a 5 digit number can be stored in one array cell, in
the character arrays only a single character can be stored in one cell. So in order to store an
array of strings, a 2-dimensional array is required.
2. As scanf( ) function is not capable of receiving multi word string, such strings should be
entered using gets( ).
int i, a - 2, b - 3 ;
int arr.[ 2 +3] ;
for (i0;i<a+b;i++ )
{
scanf( "%d", &rarr[i] ) ;
printf ( " \ n%d", arr[i] ) ;
}
}
Data Structures
elements:
int b[2][5];
The array b has 10 (2 * 5) elements, each capable of storing an integer type data, referenced as:
b[0][0] b[0][1] b[0][2] b[0][3] b[0][4]
b[1][0] b[1][1] b[1][2] b[1][3] b[1][4]
Multidimensional arrays can be declared on the similar lines. A three dimensional array (named
c) of int type has been declared below:
Int c[2][2][5];
The array c has 20 (2 * 2 * 5) elements, each capable of storing an integer type data, referenced
as:
c[0][0][0] c[0][0][1] c[0][0][2] c[0][0][3] c[0][0][4]
c[0][1][0] c[0][1][1] c[0][1][2] c[0][1][3] c[0][1][4]
c[1][0][0] c[1][0][1] c[1][0][2] c[1][0][3] c[1][0][4]
c[1][1][0] c[1][1][1] c[1][1][2] c[1][1][3] c[1][1][4]
Two-dimensional Arrays
Two dimensional arrays may be initialized by a list of initial values enclosed in braces following
their declaration.
If the values are missing in an initializer, they are automatically set to 0. For instance, the statement
static int table [2] [3] = {{1, 1},
{2}};
will initialize the first two elements of the first row to one, the first element of the second row to
two, and all the other elements to 0.
When all the elements are to be initialized to 0, the following short cut method may be used.
static int m [3] [5] = {{0}, {0}, {0}};
The first element of each row is explicitly initialized to 0 while other elements are automatically
initialized to 0.
While initializing an array, it is necessary to mention the second (column) dimension, whereas the
first dimension (row) is optional. Thus, the following declarations are acceptable.
static int arr [2] [3] = {12, 34, 23, 45, 56, 45};
static int arr[ ] [3] = {12, 34, 23, 45, 56, 45 };
Multi-dimensional Array
Data Structures
{
int num [6];
int count;
for (count = 0; count < 6; count ++)
{
printf (“\n Enter %d element:” count+1);
scanf (“%d”, &num [count]);
}
}
In this example, using the for loop, the process of asking and receiving the marks is accomplished.
When count has the value zero, the scanf( ) statement will cause the value to be stored at num [0].
This process continues until count has the value greater than 5.
Case Study: Each element of the array has a memory address. The following program prints
an array limit value and an array element address.
Program:
#include <stdio.h>
void printarr(int a[]);
main()
{
int a[5];
for(int i = 0;i<5;i++)
{
a[i]=i;
}
printarr(a);
}
void printarr(int a[])
{
for(int i = 0;i<5;i++)
{
printf(“value in array %d\n”,a[i]);
}
}
void printdetail(int a[])
{
for(int i = 0;i<5;i++)
{
printf(“value in array %d and address is %16lu\n”,a[i],&a[i]);
\\ A
}
}
Explanation
1. The function printarr prints the value of each element in arr.
2. The function printdetail prints the value and address of each element as given in statement A.
Since each element is of the integer type, the difference between addresses is 2.
3. Each array element occupies consecutive memory locations.
4. You can print addresses using place holders %16lu or %p.
Questions
1. Write a program to add two 6 x 6 matrices.
2. Write a program to multiply any two 3 x 3 matrices.
3. Write a program to sort all the elements of a 4 x 4 matrix.
4. Write a program to obtain the determinant value of a 5 x 5 matrix.
Data Structures
Example:Now, consider the following function, which takes an array as an argument along
with another argument and based on the passed arguments, it returns the average of the numbers
passed through the array as follows −
double getAverage(int arr[], int size)
{
int i;
double avg;
double sum = 0;
#include <stdio.h>
double getAverage(int arr[], int size);
int main () {
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
avg = getAverage( balance, 5 ) ;
printf( "Average value is: %f ", avg );
return 0;
}
Summary
An array is a group of memory locations related by the fact that they all have the same name
and same data type.
An array including more than one dimension is called a multidimensional array.
The size of an array should be a positive number. If an array in declared without a size and in
initialized to a series of values it is implicitly given the size of number of initializers.
Array subscript always starts with 0. Last element’s subscript is always one less than the size
of the array e.g., an array with 10 elements contains element 0 to 9. Size of an array must be a
constant number.
Keywords
Array: A user defined simple data structure which represents a group of same type of variables
having same name each being referred to by an integral index
Multidimensional array: An array in which elements are accessed using multiple indices
One dimensional array: An array in which elements are accessed using a single index
Subscript/Index: The integral index by which an array element is accessed
Two dimensional array: An array in which elements are accessed using two indices
SelfAssessment
1. What is an Array?
A. A group of elements of same data type.
B. An array contains more than one element.
C. Array elements are stored in memory in continuous or contiguous locations.
D. All the above.
3. Arrays can
A. store data elements of same data type at contiguous memory location.
B. be used for CPU scheduling.
C. be used for reverse data elements, sort data elements etc.
D. All of above
Data Structures
void main()
int i = 0, j = 0;
printf("%d", a[i][j]);
A. 1 2 3 4 5 0
B. 1 2 3 4 5 junk
C. 1 2 3 4 5 5
D. Run time error
13. Array can be considered as set of elements stored in consecutive memory locations but
having __________.
A. Same data type
B. Different data type
C. Same scope
D. None of these
Answers forSelfAssessment
1. D 2. B 3. D 4. D 5. D
6. A 7. B 8. A 9. C 10. B
Review Questions
1. Explain the usefulness of Arrays in C.
2. What do you mean by ‘Array’? How it can be declared & initialized in a C program?
3. Draw a diagram to represent the internal storage of an Array.
4. Describe the different types of Array. Give suitable programs.
5. Find the smallest number in an array using pointers.
6. If an array arr contains n elements, then write a program to check if arr[0] = arr[n-1], arr[1] =
arr[n-2] and so on.
7. Write a program to copy the contents of one array into another in the reverse order.
8. Write a program to pick up the largest number from any 5 row by 5 column matrix.
9. Write a program to obtain transpose of a 4 x 4 matrix. The transpose of a matrix is
obtainedby exchanging the elements of each row with the elements of the corresponding
column.
10. Write a program that interchanges the odd and even components of an array.
Data Structures
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/Arrays.html
https://www.javatpoint.com/c-array
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 05: Operations on arrays
Objectives
After studying this unit, you will be able to:
Explain arrays
Describe two dimensional array
Describe array initialization
Introduction
An array is a group of data items of same data type that share a common name. Ordinary variables
are capable of holding only one value at a time. If we want to store more than one value at a time in
a single variable, we use arrays.
An array is a collective name given to a group of similar quantities. Each member in the group is
referred to by its position in the group.
Arrays are allotted the memory in a strictly contiguous fashion. The simplest array is one
dimensional array which is simply a list of variables of same data type. An array of one
dimensional arrays is called a two dimension array.
5.1 Arrays
Arrays are allocated the memory in a strictly contiguous fashion. The simplest array is one
dimensional array which is a list of variables of same data type. An array of one dimensional arrays
is called a two dimensional array; array of two dimensional arrays is three dimensional array and
so on.
The members of the array can be accessed using positive integer values (indicating their order in
the array) called subscript or index. Look at an array of integers as shown below:
Data Structures
1. One-dimensional Array
A list of items can be given one variable name using only one subscript and such a variable is called
a one dimensional array.
Example: If we want to store a set of five numbers by an array variable number. Then it will
be accomplished in the following way:
int number [5];
This declaration will reserve five contiguous memory locations capable of storing an integer type
value each, as shown below:
As C performs no bounds checking, care should be taken to ensure that the array indices are within
the declared limits. Also, indexing in C begins from 0 and not from 1.
This is a table of four rows and three columns. Such a table of items can be defined using two
dimensional arrays.
General form of declaring a 2-D array is
data_typearray_name [row_size] [colum_size];
1. Traversing an Array
Traversing an array means accessing each and all elements of the array for a particular purpose.
Traversing the data elements of an array can include print every element, calculating the total
number of elements, or conducting any process on these elements.
Lab Exercise
Program to read and display numbers:
#include <stdio.h>
int main()
{
int i, n, arr[20];
printf("\n Enter the number of elements to store in the array : ");
scanf("%d", & n);
for(i=0;i<n;i++)
{
Data Structures
Output
Lab Exercise
n = n + 1;
while( j>= k) {
LA[j+1] = LA[j];
j = j - 1;
}
LA[k] = item;
Output
Task
Lab Exercise
Program to search an element from array
#include <stdio.h>
#define MAX_SIZE 100 // Maximum array size
Data Structures
int main()
{
int arr[MAX_SIZE];
int size, i, toSearch, found;
printf("Enter size of array: ");
scanf("%d", &size);
printf("Enter elements in array: ");
for(i=0; i<size; i++)
{
scanf("%d", &arr[i]);
}
printf("\nEnter element to search: ");
scanf("%d", &toSearch);
found = 0;
for(i=0; i<size; i++)
{
if(arr[i] == toSearch)
{
found = 1;
break;
}
}
if(found == 1)
{
printf("\n%d is found at position %d", toSearch, i + 1);
}
else
{
printf("\n%d is not found in the array", toSearch);
}
return 0;
}
Output
Lab Exercise
Program to delete an element from array
#include <stdio.h>
int main() {
int LA[] = {1,3,5,7,8};
int k = 3, n = 5;
int i, j;
j = k;
while( j< n) {
LA[j-1] = LA[j];
j = j + 1;
}
n = n -1;
Data Structures
Lab Exercise
int main()
{
int arr1[10], arr2[10], arr3[20];
int i, n1, n2, m, index=0;
{
printf("\n arr2[%d] = ", i);
scanf("%d", & arr2[i]);
}
m = n1+n2;
for(i=0;i<n1;i++)
{
arr3[index] = arr1[i];
index++;
}
for(i=0;i<n2;i++)
{
arr3[index] = arr2[i];
index++;
}
printf("\n\n The merged array is");
for(i=0;i<m;i++)
printf("\n arr[%d] = %d", i, arr3[i]);
return 0;
}
Output
Data Structures
Summary
An array is a group of memory locations related by the fact that they all have the same name
and same data type.
An array including more than one dimension is called a multidimensional array.
The size of an array should be a positive number. If an array in declared without a size and in
initialized to a series of values it is implicitly given the size of number of initializers.
Array subscript always starts with 0. Last element’s subscript is always one less than the size of
the array e.g., an array with 10 elements contains element 0 to 9. Size of an array must be a
constant number.
Keywords
Array: A user defined simple data structure which represents a group of same type of variables
having same name each being referred to by an integral index
Multidimensional array: An array in which elements are accessed using multiple indices
One dimensional array: An array in which elements are accessed using a single index
Subscript/Index: The integral index by which an array element is accessed
Two dimensional array: An array in which elements are accessed using two indices.
SelfAssessment
B. False
10. Deletion of an element from the array reduces the size of the array by________.
A. one
B. Two
C. Three
D. Four
12. After performing deletion on array, its required to re-organizing all elements of array
A. True
B. False
Data Structures
A. True
B. False
6. A 7. A 8. D 9. D 10. A
Review Questions
1. Write a program that perform insertion on an array.
2. Discuss in detail operations of an array.
3. What do you mean by ‘Array’? How it can be declared & initialized in a C program?
4. Draw a diagram to represent the internal storage of an Array.
5. Describe the different types of Array. Give suitable programs.
6. Delete the element from an array.
7. If an array arr contains n elements, then write a program to check if arr[0] = arr[n-1], arr[1] =
arr[n-2] and so on.
8. Write a program to merge different arrays.
9. Write a program to pick up the largest number from any 5 row by 5 column matrix.
10. Write a program that interchanges the odd and even components of an array.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/Arrays.html
https://www.javatpoint.com/c-array
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 06: Linked Lists
Objectives
After studying this unit, you will be able to:
• Dynamic Memory Management
• Understand the basics of linked list
• Discuss the operations of linked lists
Introduction
A data structure consists of a group of data elements bound by the same set of rules. The data
elements also known as members are of different types and lengths. We can manipulate data stored
in the memory with the help of data structures. The study of data structures involves examining the
merging of simple structures to form composite structures and accessing definite components from
composite structures. An array is an example of one such composite data structure that is derived
from a primitive data structure.
An array is a set of similar data elements grouped together. Arrays can be one-dimensional or
multidimensional. Arrays store the entries sequentially. Elements in an array are stored in
continuous locations and are identified using the location of the first element of the array.
Data Structures
malloc malloc (sz ) Allocate a block of size sz bytes from memory heap and return
a pointer to the allocated block
e.g., ptr = (cast.type*) malloc (byte_size);
calloc calloc in (sz) Allocate a block of size n x sz bytes from memory heap,
initialize it to zero and return a pointer to the allocated block
e.g., ptr = (cast_type*) calloc (n, elem_size);
realloc realloc (bl,; sz) Adjust the size of the memory block blk allocated on the heap
to sz, copy the contents to a new location if necessary and
return a pointer to the allocated block
e.g., ptr = realloc (ptr, newsize);
free free (blk) Free block of memory blk allocated from memory heap
e.g., free (ptr);
When we don't know how much memory will be required for the software ahead of time.
When we need data structures that don't have a memory restriction.
When you wish to make better use of your memory space.
For example, if you allocate memory space for a 1D array like array[20] and only use 10
memory spaces, the remaining 10 memory spaces will be squandered, and this wasted
memory will be unavailable to other programme variables.
Insertions and deletions in dynamically constructed lists may be done quickly and easily
by manipulating addresses, whereas insertions and deletions in statically allocated
memory result in additional movements and memory waste.
Dynamic memory allocation is required when using the concepts of structures and linked
lists in programming.
Data Structures
1. Data
2. Previous Link
3. Next Link
Example:
Program:
# include <stdio.h>
# include <stdlib.h>
struct node
{
int data;
struct node *link;
};
struct node *insert(struct node *p, int n)
{
struct node *temp;
/* if the existing list is empty then insert a new node as the
starting node */
if(p==NULL)
{
p=(struct node *)malloc(sizeof(struct node)); /* creates new
node data value passes
as parameter */
if(p==NULL)
{
printf(“Error\n”);
exit(0);
}
p-> data = n;
p-> link = p; /* makes the pointer pointing to itself because
it is a circular list*/
}
else
{
temp = p;
/* traverses the existing list to get the pointer to the last node
of it */
while (temp->link != p)
temp = temp->link;
temp-> link = (struct node *)malloc(sizeof(struct node)); /*
creates new node using
data value passes as
parameter and puts its
address in the link field
Data Structures
Lab Exercise:
# include <stdio.h>
# include <stdlib.h>
struct node *delet( struct node *, int );
int length ( struct node * );
struct node
{
int data;
struct node *link;
};
struct node *insert(struct node *p, int n)
{
struct node *temp;
if(p==NULL)
{
p=(struct node *)malloc(sizeof(struct node));
if(p==NULL)
{
printf(“Error\n”);
exit(0);
}
p-> data = n;
p-> link = NULL;
}
else
{
temp = p;
while (temp->link != NULL)
Data Structures
temp = temp->link;
temp-> link = (struct node *)malloc(sizeof(struct node));
if(temp -> link == NULL)
{
printf(“Error\n”);
exit(0);
}
temp = temp->link;
temp-> data = n;
temp-> link = NULL;
}
return (p);
}
void printlist( struct node *p )
{
printf(“The data values in the list are\n”);
while (p!= NULL)
{
printf(“%d\t”,p-> data);
p = p->link;
}
}
void main()
{
int n;
int x;
struct node *start = NULL;
printf(“Enter the nodes to be created \n”);
scanf(“%d”,&n);
while ( n- > 0 )
{
printf( “Enter the data values to be placed in a node\n”);
scanf(“%d”,&x);
start = insert ( start, x );
}
printf(“ The list before deletion id\n”);
printlist( start );
printf(“% \n Enter the node no \n”);
scanf( “ %d”,&n);
start = delet (start , n );
Data Structures
}
return(p);
}
/* a function to compute the length of a linked list */
int length ( struct node *p )
{
int count = 0 ;
while ( p != NULL )
{
count++;
p = p->link;
}
return ( count ) ;
}
6.6 Inserting a Node after the Specified Node in a Singly Linked List
To insert a new node after the specified node, first we get the number of the node in an existinglist
after which the new node is to be inserted. This is based on the assumption that the nodes ofthe list
are numbered serially from 1 to n. The list is then traversed to get a pointer to the node,whose
number is given. If this pointer is x, then the link field of the new node is made to point tothe node
pointed to by x, and the link field of the node pointed to by x is made to point to the newnode.
Figures 2.3 and 2.4 show the list before and after the insertion of the node, respectively.
Insertion in Linked List can happen at following places:
At the beginning of the linked list.
At the end of the linked list.
At a given position in the linked list.
Data Structures
4. Not considering special cases of inserting/removing at the beginning or the end of thelinked list.
5. Applying the delete operator to a node (calling the operator on a pointer to the node)before it is
removed. Delete should be done after all pointer manipulations are completed.
6. Pointer manipulations that are out of order. These can ruin the structure of the linked list.
Memory is allocated during the compile time Memory is allocated during the run-time
(Static memory allocation). (Dynamic memory allocation).
Size of the array must be specified at the time of Size of a Linked list grows/shrinks as and when
array declaration/initialization. new elements are inserted/deleted.
Summary
An array is a set of same data elements grouped together. Arrays can be one-dimensional
ormultidimensional.
A linear or one-dimensional array is a structured collection of elements (often called as array
elements) that are accessed individually by specifying the position of each element with a
single index value.
Multidimensional arrays are nothing but "arrays of arrays". Two subscripts are used to refer to
the elements.
The operations that are performed on an array are adding, sorting, searching, and traversing.
Traversing an array refers to moving in inward and outward direction to access each element
in an array.
Linked list is a technique of dynamically implementing a list using pointers. A linked list
contains two fields namely, data field and link field.
A singly-linked list consists of only one pointer to point to another node and the last node
always points to NULL to indicate the end of the list.
A doubly-linked list consists of two pointers, one to point to the next node and the other to
point to the previous node.
In a circular singly-linked list, the last node always points to the first node to indicate the
circular nature of the list.
A circular doubly-linked list consists of two pointers for forward and backward traversal and
the last node points to the first node.
Searching operation involves searching for a specific element in the list using an associated
key.
Insertion operation involves inserting a node at the beginning or end of a list.
Deletion operation involves deleting a node at the beginning or following a given node or at
the end of a list.
Keywords
Non-linear Data Structure: Every data item is attached to several other data items in a way
thatis specific for reflecting relationships. The data items are not arranged in a sequential structure.
Searching: Finding the location of the record with a given key value, or fi nding the locations ofall
records, which satisfy one or more conditions.
Traversing: Accessing each record exactly once so that certain items in the record may
beprocessed.
Circular Linked List: A linear linked list in which the last element points to the fi rst element,
thus,forming a circle.
Doubly Linked List: A linear linked list in which each element is connected to the two
nearestelements through pointers.
SelfAssessment
1. A linear collection of data elements where the linear node is given by means of pointer is
called?
A. Linked list
B. Node list
Data Structures
C. Primitive list
D. None of these
A. Static
B. Compile time
C. Heap
D. Dynamic
4. Among 4 header files, which should be included to use the memory allocation functions like
malloc(), calloc(), realloc() and free()?
A. #include<string.h>
B. #include<stdlib.h>
C. #include<memory.h>
D. All of above
10. Which of the following operations is performed for visit nodes in linked list?
A. Deletion
B. User Define Function
C. Traversing
D. None of above
11. Which of the following operations is performed for visit nodes in linked list?
A. Deletion
B. User Define Function
C. Traversing
D. None of above
16. Which of the following operation remove node from linked list
A. Traversing
B. Inversing
C. Deletion
D. Insertion
6. A 7. B 8. C 9. B 10. C
Data Structures
16. C
Review Questions
1. Define array and its types.
2. Give an example of multidimensional array.
3. Discuss any two types of array initialization methods with example.
4. Discuss different sorting methods.
5. Write a program to sort the elements of a linked list.
6. Differentiate between array and linked list with suitable example.
7. Discuss different operation performed with linked list.
8. Discuss advantages of linked list as compared to arrays.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/Arrays.html
https://www.tutorialspoint.com/data_structures_algorithms/linked_list_algorithms.htm
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 07: Doubly Linked Lists
Objectives
After studying this unit, you will be able to:
Introduction
Data Structures are the programmatic way of storing data so that data can be used efficiently.
Almost every enterprise application uses various types of data structures in one or the other way.
This tutorial will give you a great understanding on Data Structures needed to understand the
complexity of enterprise level applications and need of algorithms, and data structures.
Doubly Linked List is a variation of Linked list in which navigation is possible in both ways, either
forward or backward easily as compared to Single Linked List.
Circular Linked List is a variation of Linked list in which the first element points to the last element
and the last element points to the first element. Both Singly Linked List and Doubly Linked List can
be made into a circular linked list.
Data Structures
Advantages and Disadvantages of Doubly Linked List over Singly Linked List
Traversal can be done in both directions (from the start node to the end node as well as from
the end node to the start node) in a Doubly Linked list. But this is not possible in a Singly
Linked List and it can only be traversed only in one direction.
Deletion and insertion operations are easy to implement in a Doubly LL than a Singly LL.
For example, in a singly linked list, to delete a node, the pointer to the previous node is
needed for which the list is to be traversed. In a Doubly LL, we just need to know the
pointer of the node to be deleted.
Memory has to be allocated for both the next and previous pointers in a node. Hence, the
occupation of memory is higher in Doubly LL.
Both the pointers will have to be modified if any kind of operation is performed like
insertion, deletion, etc in case of Doubly LL.
Data
Address of the next node
Address of the previous node
Data Structures
6. Display backwards: it will display the elements from the end to the beginning.
7. Search: Search operation helps in searching an element by traversing it.
Lab Exercise
//Program
#include<stdio.h>
#include<stdlib.h>
void create(int);
int traverse();
struct node
{
int data;
struct node *next;
struct node *prev;
};
struct node *head;
void main ()
{
int choice,item;
do
{
printf("1.Insert In Doubly Linked List\n2.Traverse Doubly Linked List\n3.Exit\n4.Enter your
choice?");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the item\n");
scanf("%d",&item);
create(item);
break;
case 2:
traverse();
break;
case 3:
exit(0);
break;
default:
printf("\nPlease enter valid choice\n");
}
}while(choice != 3);
}
void create(int item)
{
Data Structures
printf("\nEmpty List\n");
}
else
{
ptr = head;
while(ptr != NULL)
{
printf("%d\n",ptr->data);
ptr=ptr->next;
}
}
}
ptr->next = NULL;
ptr->prev=NULL;
ptr->data=item;
head=ptr;
In the second scenario, the condition head == NULL become false and the node will be inserted in
beginning. The next pointer of the node will point to the existing head pointer of the node. The prev
pointer of the existing head will point to the new node being inserted.
ptr→prev
→prev =NULL
=NULL
head = ptr
Algorithm:
Step 1: IF ptr = NULL
Write OVERFLOW
Go to Step 9
[END OF IF]
Step 2: SET NEW_NODE = ptr
Step 3: SET ptr = ptr -> NEXT
Step 4: SET NEW_NODE -> DATA = VAL
Step 5: SET NEW_NODE -> PREV = NULL
Step 6: SET NEW_NODE -> NEXT = START
Step 7: SET head -> PREV = NEW_NODE
Step 8: SET head = NEW_NODE
Step 9: EXIT
Lab Exercise
#include<stdio.h>
#include<stdlib.h>
void insertbeginning(int);
struct node
{
int data;
struct node *next;
struct node *prev;
Data Structures
};
struct node *head;
void main ()
{
int choice,item;
do
{
printf("\nEnter the item which you want to insert?\n");
scanf("%d",&item);
insertbeginning(item);
printf("\nPress 0 to insert more ?\n");
scanf("%d",&choice);
}while(choice == 0);
}
void insertbeginning(int item)
{
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
ptr->data=item;
head=ptr;
}
else
{
ptr->data=item;
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
}
The temp would point to the specified node at the end of the for loop. The new node needs to be
inserted after this node therefore we need to make a fer pointer adjustments here. Make the next
pointer of ptr point to the next node of temp.
Algorithm
Step 1: IF PTR = NULL
Write OVERFLOW
Go to Step 15
[END OF IF]
Data Structures
Lab Exercise
#include<stdio.h>
#include<stdlib.h>
void insert_specified(int);
void create(int);
struct node
{
int data;
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
ptr->data=item;
head=ptr;
Data Structures
}
else
{
ptr->data=item;printf("\nPress 0 to insert more ?\n");
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
printf("\nNode Inserted\n");
}
}
void insert_specified(int item)
{
temp->next = ptr;
temp->next->prev=ptr;
printf("Node Inserted\n");
}
}
Check whether the list is empty or not. The list is empty if the condition head == NULL holds. In
that case, the node will be inserted as the only node of the list and therefore the prev and the next
pointer of the node will point to NULL and the head pointer will point to this node.
ptr->next = NULL;
ptr->prev=NULL;
ptr->data=item;
head=ptr;
In the second scenario, the condition head == NULL become false. The new node will be inserted as
the last node of the list. For this purpose, we have to traverse the whole list in order to reach the last
node of the list. Initialize the pointer temp to head and traverse the list by using this pointer.
Temp = head;
while (temp != NULL)
{
temp = temp → next;
}
the pointer temp point to the last node at the end of this while loop. Now, we just need to make a
few pointer adjustments to insert the new node ptr to the list. First, make the next pointer of temp
point to the new node being inserted i.e.ptr.
temp→next =ptr ;
make the previous pointer of the node ptr point to the existing last node of the list i.e. temp.
make the next pointer of the node ptr point to the null as it will be the new last node of the list.
ptr → next = NULL
Algorithm
Data Structures
Lab Exercise
#include<stdio.h>
#include<stdlib.h>
void insertlast(int);
struct node
{
int data;
struct node *next;
struct node *prev;
};
}
else
{
ptr->data=item;
if(head == NULL)
{
ptr->next = NULL;
ptr->prev = NULL;
head = ptr;
}
else
{
temp = head;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next = ptr;
Data Structures
ptr ->prev=temp;
ptr->next = NULL;
}
printf("\nNode Inserted\n");
}
}
1. Deletion at beginning
Deletion in doubly linked list at the beginning is the simplest operation. We just need to copy the
head pointer to pointer ptr and shift the head pointer to its next.
Ptr = head;
head = head → next;
now make the prev of this new head node point to NULL. This will be done by using the following
statements.
head → prev = NULL
Algorithm
STEP 1: IF HEAD = NULL
WRITE UNDERFLOW
GOTO STEP 6
STEP 2: SET PTR = HEAD
STEP 3: SET HEAD = HEAD → NEXT
STEP 4: SET HEAD → PREV = NULL
STEP 5: FREE PTR
STEP 6: EXIT
If the list is already empty then the condition head == NULL will become true and therefore
the operation cannot be carried on.
If there is only one node in the list then the condition head → next == NULL become true. In
this case, we just need to assign the head of the list to NULL and free head in order to
completely delete the list.
Otherwise, just traverse the list to reach the last node of the list. This will be done by using
the following statements.
ptr = head;
if(ptr->next != NULL)
{
ptr = ptr ->next;
}
.
The ptr would point to the last node of the ist at the end of the for loop. Just make the next
pointer of the previous node of ptr to NULL.
free(ptr)
Algorithm
temp = head
Traverse the list until we find the desired data value.
while(temp -> data != val)
Data Structures
Algorithm
Step 1: IF HEAD = NULL
Write UNDERFLOW
Go to Step 9
[END OF IF]
Lab Exercise
#include<stdio.h>
#include<stdlib.h>
void create(int);
void delete_specified();
struct node
{
int data;
struct node *next;
struct node *prev;
};
struct node *head;
void main ()
{
int choice,item;
do
{
printf("1.Append List\n2.Delete node\n3.Exit\n4.Enter your choice?");
scanf("%d",&choice);
switch(choice)
{
case 1:
printf("\nEnter the item\n");
scanf("%d",&item);
create(item);
break;
case 2:
delete_specified();
break;
case 3:
exit(0);
break;
default:
printf("\nPlease enter valid choice\n");
}
}while(choice != 3);
}
void create(int item)
{
struct node *ptr = (struct node *)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("\nOVERFLOW\n");
Data Structures
}
else
{
if(head==NULL)
{
ptr->next = NULL;
ptr->prev=NULL;
ptr->data=item;
head=ptr;
}
else
{
ptr->data=item;
ptr->prev=NULL;
ptr->next = head;
head->prev=ptr;
head=ptr;
}
printf("\nNode Inserted\n");
}
}
void delete_specified( )
{
struct node *ptr, *temp;
int val;
printf("Enter the value");
scanf("%d",&val);
temp = head;
while(temp -> data != val)
temp = temp ->next;
if(temp -> next == NULL)
{
printf("\nCan't delete\n");
}
else if(temp -> next -> next == NULL)
{
temp ->next = NULL;
printf("\nNode Deleted\n");
}
else
{
ptr = temp ->next;
temp -> next = ptr ->next;
ptr -> next ->prev = temp;
free(ptr);
printf("\nNode Deleted\n");
}
}
Data Structures
Lab Exercise
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *head;
case 3:
begin_delete();
break;
case 4:
last_delete();
break;
case 5:
search();
break;
case 6:
display();
break;
case 7:
exit(0);
break;
default:
printf("Please enter valid choice..");
}
}
}
void beginsert()
{
struct node *ptr,*temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("\nOVERFLOW");
}
else
{
printf("\nEnter the node data?");
scanf("%d",&item);
ptr -> data = item;
if(head == NULL)
{
head = ptr;
ptr -> next = head;
}
else
Data Structures
{
temp = head;
while(temp->next != head)
temp = temp->next;
ptr->next = head;
temp -> next = ptr;
head = ptr;
}
printf("\nnode inserted\n");
}
}
void lastinsert()
{
struct node *ptr,*temp;
int item;
ptr = (struct node *)malloc(sizeof(struct node));
if(ptr == NULL)
{
printf("\nOVERFLOW\n");
}
else
{
printf("\nEnter Data?");
scanf("%d",&item);
ptr->data = item;
if(head == NULL)
{
head = ptr;
ptr -> next = head;
}
else
{
temp = head;
while(temp -> next != head)
{
temp = temp ->next;
}
temp -> next = ptr;
ptr -> next = head;
printf("\nnode inserted\n");
}
void begin_delete()
{
struct node *ptr;
if(head == NULL)
{
printf("\nUNDERFLOW");
}
else if(head->next == head)
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{ ptr = head;
while(ptr -> next != head)
ptr = ptr ->next;
ptr->next = head->next;
free(head);
head = ptr->next;
printf("\nnode deleted\n");
}
}
void last_delete()
{
struct node *ptr, *preptr;
if(head==NULL)
{
printf("\nUNDERFLOW");
}
else if (head ->next == head)
Data Structures
{
head = NULL;
free(head);
printf("\nnode deleted\n");
}
else
{
ptr = head;
while(ptr ->next != head)
{
preptr=ptr;
ptr = ptr->next;
}
preptr->next = ptr ->next;
free(ptr);
printf("\nnode deleted\n");
}
}
void search()
{
struct node *ptr;
int item,i=0,flag=1;
ptr = head;
if(ptr == NULL)
{
printf("\nEmpty List\n");
}
else
{
printf("\nEnter item which you want to search?\n");
scanf("%d",&item);
if(head ->data == item)
{
printf("item found at location %d",i+1);
flag=0;
}
else
{
while (ptr->next != head)
{
if(ptr->data == item)
{
printf("item found at location %d ",i+1);
flag=0;
break;
}
else
{
flag=1;
}
i++;
ptr = ptr ->next;
}
}
if(flag != 0)
{
printf("Item not found\n");
}
}
void display()
{
struct node *ptr;
ptr=head;
if(head == NULL)
{
printf("\nnothing to print");
}
else
{
printf("\n printing values ... \n");
Data Structures
Summary
Linked list is a technique of dynamically implementing a list using pointers. A linked list
contains two fields namely, data field and link field.
A singly-linked list consists of only one pointer to point to another node and the last node
always points to NULL to indicate the end of the list.
A doubly-linked list consists of two pointers, one to point to the next node and the other to
point to the previous node.
In a circular singly-linked list, the last node always points to the first node to indicate the
circular nature of the list.
A circular doubly-linked list consists of two pointers for forward and backward traversal and
the last node points to the first node.
Searching operation involves searching for a specific element in the list using an associated
key.
Insertion operation involves inserting a node at the beginning or end of a list.
Deletion operation involves deleting a node at the beginning or following a given node or at
the end of a list.
Keywords
Non-linear Data Structure: Every data item is attached to several other data items in a way
thatis specific for reflecting relationships. The data items are not arranged in a sequential structure.
Searching: Finding the location of the record with a given key value, or finding the locations ofall
records, which satisfy one or more conditions.
Traversing: Accessing each record exactly once so that certain items in the record may
beprocessed.
Circular Linked List: A linear linked list in which the last element points to the fi rst element,
thus,forming a circle.
Doubly Linked List: A linear linked list in which each element is connected to the two
nearestelements through pointers.
SelfAssessment
1. Which of the following statements about a doubly linked list is not correct?
A. We can navigate in both the directions
B. It requires more space than a singly linked list
C. The insertion and deletion of a node take a bit longer
D. None of above
5. What is the worst case time complexity of inserting a node in a doubly linked list?
A. O(nlogn)
B. O(logn)
C. O(n)
D. O(1)
node.getNext().setPrev(node);
head.setNext(node);
size++;
8. Which of the following operations does a doubly linked list execute more efficiently than a
singly linked list?
A. Deleting a node whose location in given
B. Searching of an unsorted list for a given item
C. Inverting a node after the node with given location
D. Traversing a list to process each node
Data Structures
10. Which of the following basic operation of doubly linked list is responsible for delete element
from list?
A. Insert a node
B. Insert node at end
C. Delete a node
D. None of above
11. Deletion at the given position in the doubly linked list is possible.
A. True
B. False
12. Is there a linked list version in which the list's last node points to the list's beginning node?
A. Singly linked list
B. Doubly linked list
C. Circular linked list
D. Multiply linked list
14. A variant of the linked list in which none of the node contains NULL pointer is?
A. Singly linked list
B. Doubly linked list
C. Circular linked list
D. None of the above
6. A 7. A 8. A 9. A 10. C
Review Questions
1. Define circular linked list.
2. Give an example of doubly linked list.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.studytonight.com/data-structures/doubly-linked-list
https://www.tutorialspoint.com/data_structures_algorithms/linked_list_algorithms.htm
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 08: Introduction to Stacks
Objectives
After studying this unit, you will be able to:
Introduction
Stacks are simple data structures and an important tool in programming language. Stacks are linear
lists which have restrictions on the insertion and deletion operations. These are special cases of
ordered list in which insertion and deletion is done only at the ends.
The basic operations performed on stack are push and pop. Stack implementation can be done in
two ways - static implementation or dynamic implementation. Stack can be represented in the
memory using a one-dimensional array or a singly linked list.
Stack is another linear data structure having a very interesting property. Unlike arrays and link
lists, an element can be inserted and deleted not at any arbitrary position but only at one end. Thus,
one end of a stack is sealed for insertion and deletion while the other end allows both the
operations.
Data Structures
A stack is said to possess LIFO (Last In First Out) property. A data structure has LIFO property if
the element that can be retrieved first is the one that was inserted last.
Push Operation
The procedure to insert a new element to the stack is called push operation. The push operation
adds an element on the top of the stack. ‘Top’ refers to the element on the top of stack. Push makes
the ‘Top’ point to the recently added element on the stack. After every push operation, the ’Top’ is
incremented by one. When the array is full, the status of stack is FULL and the condition is called
stack overflow. No element can be inserted when the stack is full
Pop Operation
The procedure to delete an element from the top of the stack is called pop operation. After every
pop operation, the ‘Top’ is decremented by one. When there is no element in the stack, the status of
the stack is called empty stack or stack underflow. The pop operation cannot be performed when it
is in stack underflow condition.
Array-based Implementation
A stack is a sequence of data elements. To implement a stack structure, an array can be used as it is
a storage structure. Each element of the stack occupies one array element. Static implementation of
stack can be achieved using arrays. The size of the array, once declared, cannot be changed during
the program execution. Memory is allocated according to the array size. The memory requirement
is determined before the compilation. The compiler provides the required memory. This is suitable
when the exact number of elements is known. The static allocation is an inefficient memory
allocation technique because if fewer elements are stored than declared, the memory is wasted and
if more elements need to be stored than declared, the array cannot expand. In both the cases, there
is inefficient use of memory.
The following pseudo-code shows the array-based implementation of a stack. In this, the elements
of the stack are of type T.
struct stk
{ T array[max_size];
/* max_size is the maximum size */
int top = -1;
/* stack top initially given value -1 */
} stack;
void push(T e)
/*inserts an element e into the stack s*/
{
if (stack.top == max_size)
printf(“Stack is full-insertion not possible”);
else
{
stack.top = stack.top + 1;
stack.array[stack.top] = e;
}
}
T pop()
/*Returns the top element from the stack */
{
T x;
if(stack.top == -1)
printf(“Stack is empty”);
else
{
x = stack.array[stack.top];
stack.top = stack.top - l;
return(x);
}
Data Structures
}
booleanempty()
/* checks if the stack is empty * /
{
boolean empty = false;
if(stack.top == -1)
empty = true else empty = false;
return(empty);
}
void initialise()
/* This procedure initializes the stack s * /
{
stack.top = -1;
}
The above implementation strategy is easy and fast since it does not have run-time overheads. At
the same time it is not flexible since it cannot handle a situation when the number of elements
exceeds max_size. Also, let us say, if max_size is derided statically to 100 and a stack actually has
only 10 elements, then memory space for the rest of the 90 elements would be wasted.
Here the memory is used dynamically. For every push operation, the memory space for one
element is allocated at run-time and the element is inserted into the stack. For every pop operation,
the memory space for the deleted element is de-allocated and returned to the free space pool.
Hence the shortcomings of the array-based implementation are overcome. But since, this allocates
memory dynamically, the execution is slowed down.
The following pseudo-code is for the pointer-based implementation of a stack. Each element of the
stack is of type T.
struct stk
{
T element;
struct stk *next;
};
struct stk *stack;
void push(struct stk *p, T e)
{
struct stk *x;
x = new(stk);
x.element = e;
x.next = NULL;
p = x;
}
Here the stack full condition is checked by the call to new which would give an error if no memory
space could be allocated.
T pop(struct stk *p)
{
struct stk *x;
if (p == NULL)
printf(“Stack is empty”);
else
{ x = p;
x = x.next;
return(p.element);
}
booleanempty(sstructstk *p)
{
if (p == NULL)
return(true);
else
return(false);
}
void initialize(struct stk *p)
{
p = NULL;
}
Data Structures
a stack in architecture of any Central Processing Unit (CPU). In this section, we would just illustrate
a few of them.
Expression Evaluation and Conversion
Parenthesis Checking
Backtracking
Function Call
String Reversal
Memory Management
Syntax Parsing
Parenthesis checker
Parenthesis checker is used for balanced Brackets in an expression. The balanced parenthesis means
that when the opening parenthesis is equal to the closing parenthesis, then it is a balanced
parenthesis.
(a+b*(c/d))
[10+20*(6+7)]
(x+y)/(c-d)
Balanced parenthesis
A = (50+25)
In the above expression there is one opening and one closing parenthesis means that both opening
and closing brackets are equal; therefore, the above expression is a balanced parenthesis.
Unbalanced parenthesis
A= [(15+25)
The above expression has two opening brackets and one closing bracket, which means that both
opening and closing brackets are not equal; therefore, the above expression is unbalanced.
Algorithm
• Infix notation
• Postfix notation (Reverse Polish Notation)
• Prefix notation (Polish Notation)
Infix Notation
Infix Notation can be represented as:
Example: 15 + 26
a+b
Postfix Notation
Postfix Notation can be represented as
operand1 operand2 operator
Example: 15 29 +
ab+
Prefix notation
Prefix notation can be represented as
operator operand1 operand2
Example: + 10 20
+ab
Infix notation is used most frequently in our day to day tasks. Machines find infix notations
tougher to process than prefix/postfix notations. Hence, compilers convert infix notations to
prefix/postfix before the expression is evaluated.
The precedence of operators needs to be taken care as per hierarchy
(^) > (*) > (/) > (+) > (-)
Brackets have the highest priority.
To evaluate an infix expression, We need to perform 2 steps:
Task: Write a program that demonstrate working of PUSH and POP operation.
Sorting
A Sorting process is used to rearrange a given array or elements based upon selected algorithm/
sort function.
Quick Sort is used for sorting a list of data elements.Quicksort is a sorting algorithm based on the
divide and conquer approach.An array is divided into subarrays by selecting a pivot
element.During array dividing, the pivot element should be positioned in such a way that elements
less than pivot are kept on the left side and elements greater than pivot are on the right side of the
pivot.The left and right subarrays are also divided using the same approach. This process continues
until each subarray contains a single element
There are many different versions of quick Sort that pick pivot in different ways.
Always pick first element as pivot.
Data Structures
Algorithm
quickSort(arr, beg, end)
if (beg < end)
pivotIndex = partition(arr,beg, end)
quickSort(arr, beg, pivotIndex)
quickSort(arr, pivotIndex + 1, end)
partition(arr, beg, end)
set end as pivotIndex
pIndex = beg - 1
for i = beg to end-1
if arr[i] < pivot
swap arr[i] and arr[pIndex]
pIndex++
swap pivot and arr[pIndex+1]
return pIndex + 1
The objective of this problem is to move the stack of disks from the source to destination, following
these rules:
1. Only one disk can be moved at a time.
2. Only the top disk can be removed.
3. No large disk can sit over a small disk.
Data Structures
Iterative Algorithm
1. At First Calculate the number of moves required i.e. "pow(2,n) - 1" where "n" is number of discs.
2. If the number of discs i.e n is even then swap Destination Rod and Auxiliary Rod.
3. for i = 1 upto number of moves:
Check if "i mod 3" == 1:
Perform Movement of top disc between Source Rod and Destination Rod.
Check if "i mod 3" == 2:
Perform Movement of top disc between Source Rod and Auxiliary Rod.
Check if "i mod 3" == 0:
Perform Movement of top disc between Auxiliary Rod and Destination Rod.
What happens when a function is called? The action of calling a function may be divided intothree
parts:
1. Passing Arguments
2. Allocating and initializing local variables
3. Transferring control to the function.
1. Passing arguments: For a parameter in C, a copy of the argument is made locally within the
function, and any changes to the parameter are made to that local copy. The effect to this scheme is
that the original input argument cannot be altered. In this method, storage for the argument is
allocated within the data area of the function.
2. Allocating and initializing local variables: After arguments have been passed, the local
variables of the function are allocated. These local variables include all those declared directly in
the function and any temporaries that must be created during the course of execution.
3. Transferring control to the function: At this point control may still not be passed to the
function because provision has not yet been made for saving the return address. If a function is
given control, it must eventually restore control to the calling routine by means of a branch.
However, it cannot execute that branch unless it knows the location to which it must return. Since
this location is within the calling routine and not within the function, the only way that the function
can know this address is to have it passed as an argument. This is exactly what happens. Aside
from the explicit arguments specified by the programmer, there is also a set of implicit arguments
that contain information necessary for the function to execute and return correctly. Chief among
these implicit arguments is the return address. The function stores this address within its own data
area. When it is ready to return control to the calling program, the function retrieves the return
address and branches to that location. Once the arguments and the return address have been
passed, control may be transferred to the function, since everything required has been done to
ensure that the function can operate on the appropriate data and then return to the calling routine
safely.
Summary
A stack is a linear data structure in which allocation and deallocation are made in a last-in-
first-out (LIFO) method.
The basic operations of stack are inserting an element on the stack (push operation) and
deleting an element from the stack (pop operation).
Stacks are represented in main memory by using one-dimensional array or a singly linked
list.
To implement a stack structure, an array can be used as its storage structure. Each element
of the stack occupies one array element. Static implementation of stack can be achieved
using arrays.
Stack is used to store return information in the case of function/procedure/subroutine
calls. Hence, one would fi nd a stack in architecture of any Central Processing Unit (CPU).
In infix notation operators come in between the operands. An expression can be evaluated
using stack data structure.
Keywords
LIFO: (Last In First Out) the property of a list such as stack in which the element which can be
retrieved is the last element to enter it.
Data Structures
SelfAssessment
A. Finding factorial
B. tower of Hanoi
C. infix to postfix
D. all of the above
7. A pointer variable which contains the location at the top element of the stack is called …..
A. Top
B. Last
C. Final
D. End
10. In the linked representation of the stack ……… behaves as the top pointer variable of stack.
A. Stop pointer
B. Begin pointer
C. Start pointer
D. Avail pointer
Data Structures
15. Which of the following is true about linked list implementation of stack?
A. In push operation, if new nodes are inserted at the beginning of linked list, then in pop
operation, nodes must be removed from end.
B. In push operation, if new nodes are inserted at the end, then in pop operation, nodes must
be removed from the beginning.
C. Both of the above
D. None of the above
6. D 7. A 8. C 9. A 10. C
Review Questions
1 What do you mean by stack? Explain different applications of stack.
2 What are the advantages of implementing a stack using dynamic memory allocation method?
3 Explain concept of tower of Hanoi.
4 what are the different methods for implementing stacks?
5 Give an example of push and pop operation using stack.
6 Write an algorithm to reverse an input string of characters using a stack.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
www.en.wikipedia.org
https://www.javatpoint.com/data-structure-stack
https://www.tutorialspoint.com/data_structures_algorithms/stack_algorithm.htm
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 09: Introduction to Queues
Objectives
After studying this unit, you will be able to:
• Learn implementation of queues
• Explain priority queue
• Discuss applications of queues
Introduction
A queue is a linear list of elements that consists of two ends known as front and rear. We can delete
elements from the front end and insert elements at the rear end of a queue. A queue in an
application is used to maintain a list of items that are ordered not by their values but by their
sequential value.
The queue abstract data type is also a widely used one with applications very common in real life.
An example comes from the operating system software where the scheduler picks up the next
process to be executed on the system from a queue data structure. In this unit, we would study the
various properties of queues, their operations and implementation strategies.
Data Structures
return underflow
end if
data = queue[front]
front ← front + 1
return true
end procedure
Example:
/*Program of queue using array*/
/*insertion and deletion in a queue*/
/*insertion and deletion in a queue*/
# include <stdio.h>
# define MAX 50
int queue_arr[MAX];
int rear = -1;
int front = -1;
void ins_delete();
void insert();
void display();
void main()
{
int choice;
while(1)
{
printf("1.Insert\n");
printf("2.Delete\n");
printf("3.Display\n");
printf("4.Quit\n");
printf("Enter your choice : \n");
scanf("%d",&choice);
switch(choice)
{
case 1 : insert();
break;
case 2 :ins_delete();
break;
case 3: ins_display();
break;
case 4: exit(1);
default:
Data Structures
printf("Wrong choice\n");
}/*End of switch*/
}/*End of while*/
}/*End of main()*/
void insert()
{
int added_item;
if (rear==MAX-1)
printf("Queue overflow\n");
else
{
if (front==-1) /*If queue is initially empty */
front=0;
printf("Enter an element to add in the queue : ");
scanf("%d", &added_item);
rear=rear+1;
queue_arr[rear] = added_item ;
}
} /*End of insert()*/
void ins_delete()
{
if (front == -1 || front > rear)
{
printf("Queue underflow\n");
return ;
}
else
{
printf("Element deleted from queue is : %d\n", queue_arr[front]);
front=front+1;
}
} /*End of delete() */
void display()
{
int i;
if (front == -1)
printf("Queue is empty\n");
else
{
printf("Elements in the queue:\n");
for(i=front;i<= rear;i++)
printf("%d ",queue_arr[i]);
printf("\n");
}
} /*End of display() */
Output:
1. Insert
2. Delete
3. Display
4. Quit
Enter your choice: 1
Enter an element to add in the queue: 25
Enter your choice: 1
Enter an element to add in the queue: 36
Enter your choice: 3
Elements in the queue: 25, 36
Enter your choice: 2
Element deleted from the queue is: 25
In this example:
1. The preprocessor directives #include are given. MAXSIZE is defined as 50 using the #define
statement.
2. The queue is declared as an array using the declaration int queue_arr[MAX].
3. In the while loop, the different options are displayed on the screen and the value entered in the
variable choice is accepted.
4. The switch case compares the value entered and calls the method corresponding to it. If the value
entered is invalid, it displays the message “Wrong choice”.
5. Insert method: The insert method inserts item in the queue. The if condition checks whether the
queue is full or not. If the queue is full, the “Queue overflow” message is displayed. If the queue is
not full, the item is inserted in the queue and the rear is incremented by 1.
6. Delete method: The delete method deletes item from the queue. The if condition checks whether
the queue is empty or not. If the queue is empty, the “Queue underflow” message is displayed. If
the queue is not empty, the item is deleted and front is incremented by 1.
7. Display method: The display method displays the contents of the queue. The if condition checks
whether the queue is empty or not. If the queue is not empty, it displays all the items in the queue.
Circular Queue
In a circular queue, the last element points to the first element making a circular link. In a circular
queue, the rear end is connected to the front end forming a circular loop. An advantage of circular
queue is that, the insertion and deletion operations are independent of one another. This prevents
an interrupt handler from performing an insertion operation at the same time when the main
function is performing a deletion operation.
Data Structures
Double ended queue is also known as deque. It is a type of queue where the insertions and
deletions happen at the front or the rear end of the queue. The various operations that can be
performed on the double ended queue are:
1. Insert an element at the front end
2. Insert an element at the rear end
3. Delete an element at the front end
4. Delete an element at the rear end
Example:
Program for Implementation of Circular Queue.
#include<stdio.h>
#include<conio.h>
#define SIZE 5
int Q_F(int COUNT)
{
return (COUNT==SIZE)? 1:0;
}
int Q_E(int COUNT)
{
return (COUNT==0)? 1:0;
}
void rear_insert(int item, int Q[], int *R, int *COUNT)
{
if(Q_F(*COUNT))
{
printf("Queue overflow");
return;
}
*R=(*R+1) % SIZE;
Q[*R]=num;
*COUNT+=1;
}
void front_delete(int Q[], int *F, int *COUNT)
{
if(Q_E(*COUNT))
{
printf("Queue underflow");
return;
}
printf("The deleted element is %d\n", Q[*F]);
*F=(*F+1) % SIZE;
*COUNT-=1;
}
void display(int Q[], int F, int COUNT)
{
int i,j;
if(Q_E(COUNT))
{
printf("Queue is empty\n");
return;
}
printf("The contents of the queue are:\n");
i=F;
for(j=1;j<=COUNT; j++)
{
printf("%d\n", Q[i]);
i=(i+1) % SIZE;
}
printf("\n");
}
void main()
{
int choice, num, COUNT, F, R, Q[20];
clrscr();
F=0;
R=-1;
COUNT=0;
for(;;)
{
printf("1. iInsert at front\n");
printf("2. Delete at rear end\n");
printf("3. Display\n");
printf("4. Exit\n");
scanf("%d", &choice);
switch(choice)
{
case 1: printf("Enter the number to be inserted\n");
scanf("%d", &num);
rear_insert(num, Q, &R, &COUNT);
break;
case 2: front_delete(Q, &F, &COUNT);
break;
Data Structures
5. When the user enters 1, rear_insert() function is called. In the rear_insert() function, the if loop
checks if the count is full. If the condition is true, then the program prints a message “Queue is
empty”. Else, it checks for the value of R and assigns the element (num) entered by the user to R.
Initially, when there are no elements in the queue, the value of R will be 0. After every insertion, the
variable COUNT is incremented.
6. When the user enters 2, the front_delete() function is called. In this function, the if loop checks if
the variable COUNT is empty. If the condition is true, then the program prints a message “Queue
underflow”. Else, the element in the 0th
7. When the user enters 3, the display() function is called. In this function, the if loop checks if the
value of COUNT is 0. If the condition is true, the program prints a message “Queue is empty”. Else,
the value of F is assigned to the variable i. The for loop then displays the elements present in the
queue. position will be deleted. The size of F is computed and the COUNT is set to 1.
8. When the user enters 4, the program terminates.
Priority Queue
In priority queue, the elements are inserted and deleted based on their priority. Each element is
assigned a priority and the element with the highest priority is given importance and processed
first. If all the elements present in the queue have the same priority, then the first element is given
importance.
A priority queue is an abstract data type in which each element is associated with a priority
value.Elements are served on the basis of their priority.An element with high priority is dequeued
before an element with low priority.If two elements have the same priority, they are served
according to their order in the queue.
The priority queue moves the highest priority elements at the beginning of the priority queue and
the lowest priority elements at the back of the priority queue.It supports only those elements that
are comparable. Priority queue in the data structure arranges the elements in either ascending or
descending order.
Data Structures
Linked list
Heap data structure
Binary search tree
1. Array
2. Linked List
Queue implementation Using Array
To represent a queue we require a one-dimensional array of some maximum size say n to hold the
data items and two other variables front and rear to point to the beginning and the end of the
queue.
Queue implemented using array stores only fixed number of data values. Two variables front
andrear, that are implemented in queue. Front and rear variables point to the position from where
insertions and deletions are performed in a queue.
Initially both front and rear are set to -1.For insert a new value into the queue, increment rear value
by one and then insert at that position. For delete a value from the queue, then delete the element
which is at front position and increment front value by one.
Enqueue operation
Enqueue() function is used to insert a new element into the queue. In a queue, the new element is
always inserted at rear position. The enQueue() function takes one integer value as a parameter and
inserts that value into the queue.
Dequeue operation
Dequeue() is a function used to delete an element from the queue. In a queue, the element is always
deleted from front position. The Dequeue() function does not take any value as parameter.
Insert operation
There can be the two scenario of inserting this new node ptr into the linked queue.In the first
scenario, we insert element into an empty queue. In this case, the condition front = NULL becomes
true.In the second case, the queue contains more than one element. The condition front = NULL
becomes false.
Algorithm
Step 1: Allocate the space for the new node PTR
Step 2: SET PTR -> DATA = VAL
Step 3: IF FRONT = NULL
SET FRONT = REAR = PTR
SET FRONT -> NEXT = REAR -> NEXT = NULL
ELSE
SET REAR -> NEXT = PTR
SET REAR = PTR
SET REAR -> NEXT = NULL
[END OF IF]
Step 4: END
Delete operation
Deletion operation removes the element that is first inserted among all the queue elements. The
condition front == NULL becomes true if the list is empty. Otherwise, we will delete the element
that is pointed by the pointer front.
Algorithm
Step 1: IF FRONT = NULL
Write " Underflow "
Go to Step 5
[END OF IF]
Data Structures
Summary
A queue is an ordered collection of items in which deletion takes place at the front and
insertion at the rear of the queue.
In a memory, a queue can be represented in two ways; by representing the way in which the
elements are stored in the memory, and by naming the address to which the front and rear
pointers point to.
The different types of queues are double ended queue, circular queue, and priority queue.
The basic operations performed on a queue include inserting an element at the rear end and
deleting an element at the front end.
A priority queue is a collection of elements such that each element has been assigned a
priority. An element of higher priority is processed before any element of lower priority.
Two elements with the same priority are processed according to the order in which they
were inserted into the queue.
Keywords
FIFO: (First In First Out) The property of a linear data structure which ensures that the element
retrieved from it is the first element that went into it.
Front: The end of a queue from where elements are retrieved.
Queue: A linear data structure in which the element is inserted at one end while retrieved from
another end.
Rear: The end of a queue where new elements are inserted.
Dequeue: Process of deleting elements from the queue.
Enqueue: Process of inserting elements into queue.
SelfAssessment
1. A linear list of elements in which deletion can be done from one end (front) and insertion
can take place only at the other end (rear) is known as a?
A. Queue
B. Stack
C. Tree
D. Linked list
A. Dequeue
B. Enqueue
C. Push
D. Pop
4. Application of queue is
A. Serving request of a single shared resource, like a printer, CPU task scheduling
B. Call center phone system using queue to hold people calling
C. Handling of interrupt in real time system
D. All of above
6. peek() function is
Data Structures
7. isempty() function is
A. If the value of front is less than MIN or 0, it tells that queue is empty.
B. If the value of rear is less than MIN or 0, it tells that queue is empty.
C. All of above
D. None of above
A. Linear
B. Non-linear
C. Both Linear and Non Linear
D. None
13. In linked list implementation of queue, if only front pointer is maintained, which of the
following operation take worst case linear time?
A. Insertion
B. Deletion
C. To empty a queue
D. Both insertion and deletion
Data Structures
6. C 7. A 8. A 9. B 10. C
Review Questions
1 “Using double ended queues is more advantageous than using circular queues. “Discuss
2 “Stacks are different from queues.” Justify.
3 “Using priority queues is advantageous in job scheduling algorithms. “Analyze
4 Can a basic queue be implemented to function as a dynamic queue? Discuss
5 Describe the application of queue.
6 How will you insert and delete an element in queue?
7 Explain dynamic memory allocation advantages.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
www.en.wikipedia.org
www.web-source.net
www.webopedia.com
https://www.geeksforgeeks.org/
https://www.javatpoint.com/data-structure-queue
https://www.tutorialspoint.com/data_structures_algorithms/dsa_queue.htm
Dr. PrikshatKumar Angra, Lovely Professional University Unit 10: Introduction to Queues
Objectives
After studying this unit, you will be able to:
• Learn implementation of queues
• Explain priority queue
• Discuss applications of queues
Introduction
A queue is a linear list of elements that consists of two ends known as front and rear. We can delete
elements from the front end and insert elements at the rear end of a queue. A queue in an
application is used to maintain a list of items that are ordered not by their values but by their
sequential value.
The queue abstract data type is also a widely used one with applications very common in real life.
An example comes from the operating system software where the scheduler picks up the next
process to be executed on the system from a queue data structure. In this unit, we would study the
various properties of queues, their operations and implementation strategies.
Data Structures
represented as R. Before inserting an element into the queue, the R pointer should be set to -1. The
value of R is then incremented to insert the elements. In the first figure of figure 8.5, only one
element (20) is present in the queue. Hence, the value of F and R pointer will be 0. In the second
figure of figure 8.5, two elements are added (40 and 60) to the queue. This can be done by
incrementing the R pointer. The following statement depicts the increment operation:
R=(R+1) % SIZE
Here,
SIZE is the queue size. In this case, the size is 5.
In the third figure of figure 8.5, elements 80 and 100 are added to the queue. Now the R value will
be 5.Since, the value of SIZE is also 5, R will point to 0.
The above figure shows the structure of circular queue. It stores an element in a circular way and
performs the operations according to its FIFO structure.
3. New data is always added to the location pointed by the tail pointer, and once the data is
added, tail pointer is incremented to point to the next available location.
4. In a circular queue, data is not actually removed from the queue. Only the head pointer is
incremented by one position when dequeue is executed. As the queue data is only the data
between head and tail, hence the data left outside is not a part of the queue anymore,
hence removed.
5. The head and the tail pointer will get reinitialised to 0 every time they reach the end of the
queue.
Data Structures
6. Also, the head and the tail pointers can cross each other. In other words, head pointer can
be greater than the tail. Sounds odd? This will happen when we dequeue the queue a
couple of times and the tail pointer gets reinitialised upon reaching the end of the queue.
Enqueue Operation
• Check if the queue is full
• For the first element, set value of FRONT to 0
• Circularly increase the REAR index by 1 (i.E. If the rear reaches the end, next it would be
at the start of the queue)
• Add the new element in the position pointed to by REAR
Dequeue Operation
• Check if the queue is empty
• Return the value pointed by FRONT
• Circularly increase the FRONT index by 1
• For the last element, reset the values of FRONT and REAR to -1
Lab Exercise
#include<stdio.h>
# define MAX 5
int cqueue_arr[MAX];
int front = -1;
int rear = -1;
void insert(int item)
Data Structures
{
if((front == 0 && rear == MAX-1) || (front == rear+1))
{
printf("Queue Overflow \n");
return;
}
if(front == -1)
{
front = 0;
rear = 0;
}
else
{
if(rear == MAX-1)
rear = 0;
else
rear = rear+1;
}
cqueue_arr[rear] = item ;
}
void deletion()
{
if(front == -1)
{
printf("Queue Underflow \n");
return ;
}
printf("Element deleted from queue is : %d \n",cqueue_arr[front]);
if(front == rear)
{
front = -1;
rear=-1;
}
else
{
if(front == MAX-1)
front = 0;
else
front = front+1;
}
}
void display()
{
int front_pos = front,rear_pos = rear;
if(front == -1)
{
printf("Queue is empty \n");
return;
}
printf("Queue elements : ");
if( front_pos<= rear_pos )
while(front_pos<= rear_pos)
{
printf("%d ",cqueue_arr[front_pos]);
front_pos++;
}
else
{
while(front_pos<= MAX-1)
{
printf("%d ",cqueue_arr[front_pos]);
front_pos++;
}
while(front_pos<= rear_pos)
{
printf("%d ",cqueue_arr[front_pos]);
front_pos++;
}
}
printf("null");
}
int main()
{
int choice,item;
do
{
printf("\n1.Insert\n");
printf("2.Delete\n");
printf("3.Display\n");
printf("4.Quit\n");
Data Structures
10.2 Deque
Deque or Double Ended Queue is a type of queue in which insertion and removal of elements can
either be performed from the front or the rear. Thus, it does not follow FIFO rule (First in First Out).
Types of Deque
Insertion at front
Insertion at rear
Deletion at front
Deletion at rear
We can also perform peek operations in the deque along with the operations listed above. Through
peek operation, we can get the deque's front and rear elements of the deque. So, in addition to the
above operations, following operations are also supported in deque –
Applications of deque
An internet browser's history.
Another common application of the deque is storing a computer code application's list of
undo operations.
Have you ever see Money-Control App, it'll show the stocks you last visited, it'll take away
the stocks when a while and can add the most recent ones.
Deque can be used as both stack and queue, as it supports both operations.
Deque can be used as a palindrome checker means that if we read the string from both ends,
the string would be the same.
Lab Exercise
#include <stdio.h>
#define size 5
int deque[size];
int f = -1, r = -1;
// insert_front function will insert the value from the front
void insert_front(int x)
{
if((f==0 && r==size-1) || (f==r+1))
Data Structures
{
printf("Overflow");
}
else if((f==-1) && (r==-1))
{
f=r=0;
deque[f]=x;
}
else if(f==0)
{
f=size-1;
deque[f]=x;
}
else
{
f=f-1;
deque[f]=x;
}
}
deque[r]=x;
}
while(i!=r)
{
printf("%d ",deque[i]);
i=(i+1)%size;
}
printf("%d",deque[r]);
}
Data Structures
else
{
printf("\nThe value of the element at rear is %d", deque[r]);
}
}
else if(f==(size-1))
{
printf("\nThe deleted element is %d", deque[f]);
f=0;
}
else
{
printf("\nThe deleted element is %d", deque[f]);
f=f+1;
}
}
else if(f==r)
{
printf("\nThe deleted element is %d", deque[r]);
f=-1;
r=-1;
}
else if(r==0)
{
printf("\nThe deleted element is %d", deque[r]);
r=size-1;
}
else
{
printf("\nThe deleted element is %d", deque[r]);
r=r-1;
}
}
int main()
{
insert_front(10);
insert_front(5);
insert_rear(20);
insert_rear(60);
insert_rear(90);
display(); // Calling the display function to retrieve the values of deque
getfront(); // Retrieve the value at front-end
getrear(); // Retrieve the value at rear-end
delete_front();
delete_rear();
display(); // calling display function to retrieve values after deletion
return 0;
}
Output
Data Structures
10.3 Recursion
Recursion is one of the most powerful tools in a programming language, but one of the most
threatening topics-as most of the beginners and not surprising to even experience students feel.
When function is called within the same function, it is known as recursion in C. The function
which calls the same function, is known as recursive function.
Recursion is defined as defining anything in terms of itself. Recursion is used to solve problems
involving iterations, in reverse order.
Disadvantages of Recursion
1. The computer may run out of memory if the recursive calls are not checked.
2. It is not more efficient in terms of speed and execution time.
3. According to some computer professionals, recursion does not offer any concrete
advantage over non-recursive procedures/functions.
4. Recursive solution is always logical and it is very difficult to trace.(debug and
understand).
5. Recursion takes a lot of stack space, usually not considerable when the program is small
and running on a PC.
6. Recursion uses more processor time.
Iteration Recursion
In iteration,a problem is converted into a train Recursion is like piling all of those steps on top
of steps that are finished one at a time, one of each other and then quashing the mall into
after another the solution.
With iteration,each step clearly leads on to the In recursion, each step replicates itself at a
next, like stepping stones across a river smaller scale, so that all of them combined
together eventually solve the problem.
Any iterative problem is solved recursively Not all recursive problem can solved by
iteration
Summary
A queue is an ordered collection of items in which deletion takes place at the front and
insertion at the rear of the queue.
In a memory, a queue can be represented in two ways; by representing the way in which the
elements are stored in the memory, and by naming the address to which the front and rear
pointers point to.
The different types of queues are double ended queue, circular queue, and priority queue.
The basic operations performed on a queue include inserting an element at the rear end and
deleting an element at the front end.
Two elements with the same priority are processed according to the order in which they were
inserted into the queue.
Keywords
FIFO: (First In First Out) the property of a linear data structure which ensures that the element
retrieved from it is the first element that went into it.
Front: The end of a queue from where elements are retrieved.
Queue: A linear data structure in which the element is inserted at one end while retrieved from
another end.
Rear: The end of a queue where new elements are inserted.
Dequeue: Process of deleting elements from the queue.
Enqueue: Process of inserting elements into queue.
SelfAssessment
Data Structures
B. Square Buffer
C. Rectangle Buffer
D. Curve Buffer
2. A data structure in which elements can be inserted or deleted at/from both ends but not in
the middle is?
A. Queue
B. Circular queue
C. Dequeue
D. Priority queue
5. A circular queue is one in which the insertion of a new element is done at the very first
location of the queue if the last location of the queue is full.
A. True
B. False
6. A data structure in which elements can be inserted or deleted at/from both ends but not in
the middle is?
A. Queue
B. Circular queue
C. Dequeue
D. Priority queue
9. What is a dequeue?
A. A queue with insert/delete defined for both front and rear ends of the queue
B. A queue implemented with a doubly linked list
C. A queue implemented with both singly and doubly linked lists
D. None of the mentioned
if(isEmpty())
head.setNext(temp);
temp.setNext(trail);
else
Node cur=head.getNext();
while(cur.getNext()!=trail)
cur=cur.getNext();
cur.setNext(temp);
size++;
Data Structures
C. Recursive function
D. All of above
15. When any function is called from main(), the memory is allocated to it on the stack.
A. True
B. False
C. Can be true or false
D. Neither true nor false
6. C 7. C 8. D 9. A 10. B
Review Questions
1 “Using double ended queues is more advantageous than using circular queues. “Discuss
2 “Stacks are different from queues.” Justify.
3 Write a program that implement circular queue data structure.
4 Can a basic queue be implemented to function as a dynamic queue? Discuss
5 Describe the application of circular queue.
6 How will you insert and delete an element in circular queue?
7 Explain dynamic memory allocation advantages.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web links
https://www.programiz.com/dsa/circular-queue
https://www.geeksforgeeks.org/
https://www.javatpoint.com/data-structure-queue
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 11: Trees
Objectives
After studying this unit, you will be able to:
Define trees
Explain different types of trees
Discuss the applications of trees
Introduction
We know that a data structure is a collection of data pieces labelled with the same name. A data
structure can be thought of as a collection of rules for keeping data together. Data structures are
used in almost all computer programmes. Algorithms are incomplete without data structures. It can
be used to manage massive databases with large amounts of data. Data structures are prioritised in
several modern programming languages over algorithms.
There are many data structures that help us to manipulate the data stored in the memory, which we
have discussed in the previous units. These include array, stack, queue, and linked-list.
Choosing the best data structure for a program is a challenging task. Similar tasks may require
different data structures. We derive new data structures for complex tasks using the already
existing ones. We need to compare the characteristics of the data structures before choosing the
right data structure. A tree is a hierarchical data structure suitable for representing hierarchical
information. The tree data structure has the characteristics of quick search, quick inserts, and quick
deletes.
11.1 Trees
A tree is a very important data structure as it is useful in many applications. A tree structure is
amethod of representing the hierarchical nature of a structure in a graphical form. It is termed as
Data Structures
"treestructure" since its representation resembles a tree. However, the chart of a tree is normally
upsidedown compared to an actual tree, with the root at the top and the leaves at the bottom.
Figure shows tree structure of books.
In the hierarchical organization of books shown in figure 10.1, Books is the root of the tree. Books
can be classified as Fiction and Non-fiction. Non-fiction books can be further classified as Realistic
and Non-realistic, which are the leaves of the tree. Thus, it forms a complete tree structure.
Trees are primarily treated as data structures rather than as data types.
A tree is a widely-used data structure that depicts a hierarchical tree structures with a set of linked
nodes. The elements of data structure in a tree are arranged in a non-linear fashion i.e., they use two
dimensional representations. Thus, trees are known as non-linear data structures. This data
structure is more efficient in inserting additional data, deleting unnecessary data, and searching
new data.
Other data structures such as arrays, linked list, stack, and queue are linear data structures
that store data sequentially.
In order to perform any operation in a linear data structure, the time complexity increases
with the increase in the data size.
o But, it is not acceptable in today's computational world.
Different tree data structures allow quicker and easier access to the data as it is a non-
linear data structure.
Advantages of trees
Trees are so useful and frequently used, because they have some very serious advantages:
A graph G consists of a set of objects V = {v1, v2, v3 …} called vertices (points or nodes) and a set of
objects E = {e1, e2, e3 ….} called edges (lines or arcs).
The set V (G) is called the vertex set of G and E (G) is the edge set.
The graph is denoted as G = (V, E)
Let G be a graph and {u, v} an edge of G. Since {u, v} is 2-element set, we write {v, u} instead of {u,
v}.
This edge can be represented as uv or vu.
If e = uv is an edge of a graph G, then u and v are adjacent in G and e joins u and v.
In figure 10.3, the graph (i) has two different, unconnected set of nodes. Graphs can also contain
cycles. Graph (ii) has several cycles. One such path is from x1 to x2 to x4 and back to x1. Another
one is from x1 to x2 to x3 to x5 to x4 and back to x1. (There are also cycles in graph (ii).) Graph (iii)
does not have any cycles and all nodes are reachable. Therefore, it is a tree.
Tree Terminologies
Node
A node is an entity that contains a key or value and pointers to its child nodes.
Data Structures
The last nodes of each path are called leaf nodes or external nodes that do not contain a
link/pointer to child nodes.
The node having at least a child node is called an internal node.
Edge
It is the link between any two nodes.
Root
It is the topmost node of a tree.
Height of a Node
The height of a node is the number of edges from the node to the deepest leaf (ie. the longest path
from the node to a leaf node).
Depth of a Node
The depth of a node is the number of edges from the root to the node.
Degree of a Node
The degree of a node is the total number of branches of that node.
Forest
A collection of disjoint trees is called a forest.
Height of a Tree
The height of a Tree is the height of the root node or the depth of the deepest node.
1. General Tree: In the general tree, a node can have either 0 or maximum n number of
nodes. There is no restriction imposed on the degree of the node (the number of nodes
that a node can contain). The topmost node in a general tree is known as a root node. The
children of the parent node are known as subtrees.
Data Structures
2. Binary Tree: Binary name itself suggests two numbers, i.e., 0 and 1. In a binary tree, each
node in a tree can have utmost two child nodes. Here, utmost means whether the node has
0 nodes, 1 node or 2 nodes.
AVL Tree
It is one of the types of the binary tree, or we can say that it is a variant of the binary search tree.
AVL tree satisfies the property of the binary tree as well as of the binary search tree.It is a self-
balancing binary search tree that was invented by Adelson VelskyLindas.Here, self-balancing
means that balancing the heights of left subtree and right subtree. This balancing is measured in
terms of the balancing factor.
1. Linked representation
Binary trees in linked representation are stored in the memory as linked lists. These lists have nodes
that aren’t stored at adjacent or neighboring memory locations and are linked to each other through
the parent-child relationship associated with trees.
In this representation, each node has three different parts –
2. Sequential representation
Although it is simpler than linked representation, its inefficiency makes it a less preferred binary
tree representation of the two. The inefficiency lies in the amount of space it requires for the storage
of different tree elements. The sequential representation uses an array for the storage of tree
elements.
The number of nodes a binary tree has defines the size of the array being used. The root node of the
binary tree lies at the array’s first index. The index at which a particular node is stored will define
the indices at which the right and left children of the node will be stored. An empty tree has null or
0 as its first index.
Example
X>Y
X<Z
Data Structures
The properties that separate a binary search tree from a regular binary tree
1. All nodes of left subtree are less than the root node.
2. All nodes of right subtree are more than the root node.
3. Both subtrees of each node are also BSTs i.e. they have the above two properties.
A tree having a right subtree with one value smaller than the root is shown to
demonstrate that it is not a valid binary search tree.
1. Complete binary tree: All the levels in the trees are full of last level's possible exceptions.
Similarly, all the nodes are full, directing the far left.
2. Full binary tree: All the nodes have 2 child nodes except the leaf.
3. Balanced or Perfect binary tree: In the tree, all the nodes have two children. Besides, there is
the same level of each sub node.
Searching become very efficient in a binary search tree since, we get a hint at each step,
about which sub-tree contains the desired element.
The binary search tree is considered as efficient data structure in compare to arrays and
linked lists. In searching process, it removes half sub-tree at every step. Searching for an
element in a binary search tree takes o(log2n) time. In worst case, the time it takes to search
an element is 0(n).
It also speed up the insertion and deletion operations as compare to that in array and linked
list.
1. No duplicate values.
2. The left subtree of a node can only have values less than the node.
3. The right subtree of a node can only have values greater than the node and recursively
defined.
4. The left subtree of a node is a binary search tree.
5. The right subtree of a node is a binary search tree.
Example
Create the binary search tree using the following data elements
43, 10, 79, 90, 12, 54, 11, 9, 50
Insert 43 into the tree as the root of the tree.
Read the next element, if it is lesser than the root node element, insert it as the root of the left sub-
tree.
Otherwise, insert it as the root of the right of the right sub-tree.
Data Structures
11.5 Traversal
Traversal is a process to visit all the nodes of a tree and may print their values too. Because, all
nodes are connected via edges (links) we always start from the root (head) node. We cannot
randomly access a node in a tree.
Ways of traversal are
1. In-order Traversal
2. Pre-order Traversal
3. Post-order Traversal
Example
Inorder algorithm
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Visit root node.
Step 3 − Recursively traverse right subtree.
Preorder algorithm
Until all nodes are traversed −
Step 1 − Visit root node.
Step 2 − Recursively traverse left subtree.
Step 3 − Recursively traverse right subtree.
Postorder algorithm
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Recursively traverse right subtree.
Step 3 − Visit root node.
1. Recursive
2. Non Recursive
Example
// Postorder Traversal in using Recursion
#include <stdio.h>
#include <stdlib.h>
struct tree {
int val;
struct tree* left;
struct tree* right;
};
typedef struct tree TreeNode;
TreeNode* newTree(int data)
{
TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
root->val = data;
Data Structures
root->left = NULL;
root->right = NULL;
return (root);
}
void postorder(TreeNode* root)
{
if (root == NULL)
return;
postorder(root->left);
postorder(root->right);
printf("%d ", root->val);
}
int main()
{
TreeNode* t = newTree(9);
t->left = newTree(3);
t->left->left = newTree(0);
t->left->right = newTree(4);
t->left->right->left = newTree(5);
t->left->right->right = newTree(7);
t->left->right->right->left = newTree(8);
t->left->right->right->right = newTree(6);
t->right = newTree(2);
t->right->left = newTree(8);
t->right->right = newTree(10);
printf("postorder traversal of the above tree is:\n");
postorder(t);
return 0;
}
Output
Example
// Inorder Tree Traversal without Recursion
#include<stdio.h>
#include<stdlib.h>
#define bool int
struct tNode
{
int data;
struct tNode* left;
struct tNode* right;
};
struct sNode
{
struct tNode *t;
struct sNode *next;
};
void push(struct sNode** top_ref, struct tNode *t);
struct tNode *pop(struct sNode** top_ref);
bool isEmpty(struct sNode *top);
void inOrder(struct tNode *root)
{
struct tNode *current = root;
struct sNode *s = NULL;
bool done = 0;
while (!done)
{
if(current != NULL)
{
push(&s, current);
current = current->left;
}
else
{
if (!isEmpty(s))
{
current = pop(&s);
printf("%d ", current->data);
current = current->right;
}
else
done = 1;
}
}
Data Structures
}
void push(struct sNode** top_ref, struct tNode *t)
{
struct sNode* new_tNode =
(structsNode*) malloc(sizeof(struct sNode));
if(new_tNode == NULL)
{
printf("Stack Overflow \n");
getchar();
exit(0);
}
new_tNode->t = t;
new_tNode->next = (*top_ref);
(*top_ref) = new_tNode;
}
bool isEmpty(struct sNode *top)
{
return (top == NULL)? 1 : 0;
}
struct tNode *pop(struct sNode** top_ref)
{
struct tNode *res;
struct sNode *top;
if(isEmpty(*top_ref))
{
printf("Stack Underflow \n");
getchar();
exit(0);
}
else
{
top = *top_ref;
res = top->t;
*top_ref = top->next;
free(top);
return res;
}
}
struct tNode* newtNode(int data)
{
Output
Task
• Program to demonstrate working of traversal using recursive way.
• Program to demonstrate working of traversal using non recursive way.
11.6 Searching
Searching means finding or locating some specific element or node within a data structure.
However, searching for some specific node in the binary search tree is pretty easy due to the fact
that, elements in BST are stored in a particular order.
Following are steps involved in searching
Data Structures
Algorithm
Search (ROOT, ITEM)
Deletion in BST
In a binary search tree, the deletion operation is performed with O(n) time complexity. Deleting a
node from Binary search tree includes following three cases.
Example
// Program to perform insertion, deletion and searching in Tree
#include<stdio.h>
#include<stdlib.h>
struct node
{
int info;
struct node*left;
struct node*right;
};
typedef struct node BST;
BST *LOC, *PAR;
Data Structures
ptr = ptr->right;
}
}
LOC = NULL;
PAR = save;
return;
}
struct node* findmin(struct node*r)
{
if (r == NULL)
return NULL;
else if (r->left!=NULL)
return findmin(r->left);
else if (r->left == NULL)
return r;
}
struct node*insert(struct node*r, int x)
{
if (r == NULL)
{
r = (struct node*)malloc(sizeof(struct node));
r->info = x;
r->left = r->right = NULL;
return r;
}
else if (x < r->info)
r->left = insert(r->left, x);
else if (x > r->info)
r->right = insert(r->right, x);
return r;
}
struct node* del(struct node*r, int x)
{
struct node *t;
if(r == NULL)
printf("\nElement not found");
else if (x < r->info)
r->left = del(r->left, x);
else if (x > r->info)
r->right = del(r->right, x);
Data Structures
Summary
A tree structure is a way of presenting the hierarchical nature of a structure in a graphical
form.
The trees can be represented as graphs.
The three types of graphs are directed graphs, undirected graphs, and mixed graphs.
The different kinds of trees include binary tree, binary search tree, 2-3 tree, and Huffman
tree.
The two ways to represent trees are linked representation and array representation.
The applications of trees include expression trees, game trees, and decision trees.
To evaluate an expression tree, we recursively evaluate the left and right sub-trees and
then apply the operator at the root.
Keywords
Binary Search Tree:- A binary search tree follows some order to arrange the elements. In a Binary
search tree, the value of left node must be smaller than the parent node, and the value of right node
must be greater than the parent node.
Complete Binary Tree:-A complete binary tree is a binary tree in which all the levels are
completely filled except possibly the lowest one, which is filled from the left.
Tree: - A tree data structure is a non-linear data structure because it does not store in a sequential
manner.
SelfAssessment
1. Root is
A. The topmost node of a tree.
B. The child node of a tree.
C. The positive node of a tree.
D. None of above.
Data Structures
2. Degree of a Node is
A. The degree of a node is the X number of branches of that node.
B. The degree of a node is the X+Y number of branches of that node.
C. The degree of a node is the total number of branches of that node.
D. All of above.
A. General Tree
B. Primary Tree
C. Binary Tree
D. Binary Search Tree
D. All of above
10. Select the traversal method in which root is visited after visit left sub-tree and right sub-tree.
A. In order Traversal
B. Pre-order Traversal
C. Post-order Traversal
D. None of above
A. Traverse the left sub-tree, than traverse the right sub-tree, finally traverse the root
B. Traverse the root, than traverse the right sub-tree, finally traverse the left sub-tree
C. Traverse the left sub-tree, than traverse the right sub-tree
D. Traverse root only
A. True
B. False
6. D 7. C 8. D 9. D 10. C
Data Structures
Review Questions
1. “Choosing the best data structure for a program is a challenging task”. Discuss.
2. “The trees can be represented as graphs”. Justify.
3. “There are different kinds of trees and it is important to understand the difference between
them”.
Analyze.
4. Explain binary search tree.
5. What is searching in tree?
6. How insertion performed in tree.
7. Differentiate between in-order traversal and pre-order traversal.
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web links
https://www.gatevidyalay.com/tree-data-structure-tree-terminology/
https://www.javatpoint.com/searching-in-binary-search-tree
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 12: Graphs
Objectives
After studying this unit, you will be able to:
Introduction
Graph traversal entails visiting each vertex and edge in a predetermined order. You must verify
that each vertex of the graph is visited exactly once when utilizing certain graph algorithms. The
sequence in which the vertices are visited is crucial, and it may be determined by the algorithm or
question you're working on.It's critical to keep track of which vertices have been visited throughout
a traversal. Marking vertices is the most popular method of tracking them.
In Graph traversal visiting every vertex and edge exactly once in a well-defined order.In graph
algorithms, you must ensure that each vertex of the graph is visited exactly once. The order in
which the vertices are visited may depend upon the algorithm or type of problem going to solve.
Two common elementary algorithms for tree-searching are
– Breadth-first search (BFS)
– Depth-first search (DFS).
Both of these algorithms work on directed or undirected graphs. Many advanced graph algorithms
are based on the ideas of BFS or DFS. Each of these algorithms traverses edges in the graph,
discovering new vertices as it proceeds. The difference is in the order in which each algorithm
discovers the edges.
Data structures
Notes:
• Graph is an abstract data type.
• It is a pictorial representation of a set of objects where some pairs of objects are connected
by links.
• Graph is used to implement the undirected graph and directed graph concepts from
mathematics.
• It represents many real life application. Graphs are used to represent the networks.
Network includes path in a city, telephone network etc.
• It is used in social networks like Facebook, LinkedIn etc.
Graph Components
Graph consist of two components
1. Vertices
2. Edges
Example: In Facebook, each person is represented with a vertex or a node. Each node is a
structure and contains the information like user id, user name, gender etc.
V = {A, B, C, D, E, F}
E = {(A, B), (A, C), (B, C), (B, D), (D, E), (D, F), (E, F)}
V = {A, B, C, D, E, F}
E = {(A, B), (A, C), (B, D), (C, E), (C, F)}
V = {A, B, C}
E = {(A, B), (A, C), (C, B)}
Data structures
Undirected Graph
• If a graph contains unordered pair of vertices, is said to be an Undirected Graph.
• In this graph, pair of vertices represents the same edge.
• In an undirected graph, the nodes are connected by undirected arcs.
• It is an edge that has no arrow. Both the ends of an undirected arc are equivalent, there is
no head or tail.
• Path
– A path can be defined as the sequence of nodes that are followed in order to reach some
terminal node V from the initial node U.
• Closed Path
– A path will be called as closed path if the initial node is same as terminal node. A path will
be closed path if V0=VN.
• Simple Path
– If all the nodes of the graph are distinct with an exception V 0=VN, then such path P is called
as closed simple path.
• Cycle
– A cycle can be defined as the path which has no repeated edges or vertices except the first
and last vertices.
• Connected Graph
– A connected graph is the one in which some path exists between every two vertices (u, v) in
V. There are no isolated nodes in connected graph.
• Complete Graph
– A complete graph is the one in which every node is connected with all other nodes. A
complete graph contain n(n-1)/2 edges where n is the number of nodes in the graph.
• Weighted Graph
– In a weighted graph, each edge is assigned with some data such as length or weight. The
weight of an edge e can be given as w(e) which must be a positive (+) value indicating the
cost of traversing the edge.
• Digraph
– A digraph is a directed graph in which each edge of the graph is associated with some
direction and the traversing can be done only in the specified direction.
• Loop
– An edge that is associated with the similar end points can be called as Loop.
• Adjacent Nodes
– If two nodes u and v are connected via an edge e, then the nodes u and v are called as
neighbours or adjacent nodes.
• Degree of the Node
– A degree of a node is the number of edges that are connected with that node. A node with
degree 0 is called as isolated node.
1. Sequential Representation
2. Linked Representation
1. Sequential Representation
In sequential representation, we use adjacency matrix to store the mapping represented by vertices
and edges. In adjacency matrix, the rows and columns are represented by the graph vertices. A
graph having n vertices, will have a dimension n x n.
Adjacency Matrix
• An undirected graph and its adjacency matrix representation is shown in the following
figure.
• A directed graph and its adjacency matrix representation is shown in the following figure.
Data structures
• The weighted directed graph along with the adjacency matrix representation is shown in
the following figure.
2. Linked Representation
In the linked representation, an adjacency list is used to store the Graph into the computer's
memory.
Linked Representation
• Consider the undirected graph shown in the following figure and check the adjacency list
representation.
• An adjacency list is maintained for each node present in the graph which stores the node
value and a pointer to the next adjacent node to the respective node.
• If all the adjacent nodes are traversed then store the NULL in the pointer field of last node
of the list. The sum of the lengths of adjacency lists is equal to the twice of the number of
edges present in an undirected graph.
• Consider the directed graph shown in the following figure and check the adjacency list
representation of the graph.
• In the case of weighted directed graph, each node contains an extra field that is called the
weight of the node. The adjacency list representation of a directed graph is shown in the
following figure.
Data structures
Fig (a)
Fig (b)
Fig (c)
Fig (d)
Fig (e)
Data structures
Fig (f)
Fig (g)
Fig (h)
Algorithm Complexity
The time complexity of the BFS algorithm is represented in the form of O(V + E), where V is the
number of nodes and E is the number of edges.
The space complexity of the algorithm is O(V).
BFS Applications
Fig (a)
Data structures
Fig (b)
Fig (c)
Fig (d)
Fig (e)
Fig (f)
Fig (g)
Data structures
Fig (h)
Fig (i)
Fig (j)
Fig (k)
Fig (l)
Fig (m)
Algorithm Complexity
Time complexity: O(V + E), where V is the number of vertices and E is the number of edges in the
graph.
Space Complexity: O(V).
DFS Applications
Data structures
Summary
Graphs provide in excellent way to describe the essential features of many applications.
Graphs are mathematical structures and are found to be useful in problem solving. They
may be implemented in many ways by the use of different kinds of data structures.
Graph traversals, Depth first as well as Breadth First, are also required in many applications.
Breadth first search is a graph traversal algorithm that starts traversing the graph from root
node and explores all the neighboring nodes.
DFS traversal is a recursive algorithm for searching all the vertices/ nodes of a graph or tree
using stack data structure.
Keywords
Breadth-first search: -Breadth-first search is an algorithm for searching a tree data structure for a
node that satisfies a given property.
Depth-first search:-Depth first search (DFS) algorithm starts with the initial node of the graph G,
and then goes to deeper and deeper until we find the goal node or the node which has no children.
Graph: - A graph can be defined as a collection of vertices and the edges that connect them. A
graph is a cyclic tree in which the vertices (Nodes) preserve any complex relationship between
them rather than having a parent-child relationship.
Self Assessment
a)
b)
c)
Data structures
d)
5. directed graph is
A. A graph contains ordered pair of vertices.
B. A graph contains 2 pair of vertices.
C. A graph contains vertices.
D. None of the above
8. Choose the incorrect statement about DFS and BFS from the following.
A. BFS is equivalent to level order traversal in trees
B. DFS is equivalent to post order traversal in trees
C. DFS and BFS code has same time complexity
D. DFS is implemented using stack
11. The Data structure used in standard implementation of Breadth First Search is?
A. Stack
B. Queue
C. Linked List
D. Tree
6. B 7. A 8. B 9. B 10. D
Review Questions
1. “A graph in which each edge is assigned a direction is called a directed graph”. Discuss
withexample.
2. “A graph consists of a set of vertices and edges/arcs”. Explain with diagram.
3. Write and explain breadth first search algorithm.
4. Write and explain depth first search algorithm.
5. Differentiate between tree and graph.
6. Discuss in detail applications of graph data structure.
7. Explain how graphs are different from tree.
Data structures
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.simplilearn.com/tutorials/data-structure-tutorial/graphs-in-data-structure
https://www.freecodecamp.org/news/a-gentle-introduction-to-data-structures-how-
graphs-work-a223d9ef8837/
https://www.tutorialspoint.com/data_structures_algorithms/graph_data_structure.htm
Objectives
After studying this unit, you will be able to:
Understand Searching
Explain linear search
Analyze complexity
Define binary search
Introduction
The process of discovering the location LOC of an element in a list is referred to as searching in a
data structure. This is a crucial feature of many data structure algorithms, because we can only
conduct one operation on an element if and only if we discover it. To determine whether an
element is present in a collection of objects, various algorithms have been defined. Both internal
and external data structures can be used with this approach. Any algorithm's efficiency is improved
by the efficiency of searching for an element.
1. Linear Search
This is the traditional technique for searching an element in a collection of elements. In this type of
search, all the elements of the list are traversed one by one to find if the element is present in the list
or not. One example of such an algorithm is a linear search. This is a straightforward and basic
algorithm. Suppose ARR is an array of n elements, and we need to find location LOC of element
ITEM in ARR. For this, LOC is assigned to -1, which indicates that ITEM is not present in ARR.
While comparing ITEM with data at each ARR location, and once ITEM == ARR[N], LOC is
updated with location N+1. Hence we found the ITEM in ARR.
Algorithm
LSEARCH(ARR, N, ITEM, LOC) Here ARR Is the array of N number of elements, ITEM holds the
value we need to search in the array and algorithm returns LOC, the location where ITEM is
present in the ARR. Initially, we have to set LOC = -1.
1. Set LOC = -1,i=1
2. Repeat while DATA[i] != ITEM:
i=i+1
3. If i=N+1 ,then Set LOC =0
Else LOC = N+1
4. Exit.
Example: Let’s say, below is the ARR with 5 elements. And we need to find whether ITEM=
12 is present in this array or not.
22 32 12 35 65
22 32 12 35 65
12==
22 32 12 35 65
12==
22 32 12 35 65
12==
Lab Exercise
// Program
#include<stdio.h>
int main(){
int a[5]={12,2,34,55,67};
int i, toSearch,flag=0;
printf("\n Original Array is \n");
for(i=0;i<5;i++){
printf("%d \t ", a[i]);
}
printf("\n Enter element to find");
scanf("%d",&toSearch);
for(i=0;i<5;i++){
if(a[i]==toSearch)
{
flag=1;
break;
}
else
flag=0;
}
if(flag!=0)
printf("Element %d is found at location %d\n",toSearch,i);
else
printf("\n Item not found\n");
return 0;
}
Output
Space complexity
As linear search algorithm does not use any extra space, thus its space complexity = O(n) for an
array of n number of elements.
Time Complexity
Worst-case complexity: O(n) – This case occurs when the search element is not present in the array.
Best case complexity: O(1) – This case occurs when the first element is the element to be searched.
Average complexity: O(n) – This means when an element is present somewhere in the middle of
the array.
2. Binary Search
This is a technique to search an element in the list using the divide and conquer technique. This
type of technique is used in the case of sorted lists. Instead of searching an element one by one in
the list, it directly goes to the middle element of the list, divides the array into 2 parts, and decides
element lies in which sub-array the element exists.
Suppose ARR is an array with sorted n number of elements present in increasing order. With every
step of this algorithm, the searching is confined within BEG and END, which are the beginning and
ending index of sub-arrays. The index MID defines the middle index of the array where,
MID = INT(beg + end )/2
It needs to be checked if ITEM < ARR[N} where ITEM is the element that we need to search in ARR.
After this MID is again calculated for respective sub-arrays, if we didn’t find the ITEM, the
algorithm returns -1 otherwise LOC = MID.
Algorithm:
BSEARCH(ARR, LB, UB, ITEM, LOC) Here, ARR is a sorted list of elements, with LB and UB are
lower and upper bounds for the array. ITEM needs to be searched in the array and algorithm
returns location LOC, index at which ITEM is present else return -1.
Else:
Set LOC = NULL
6. Exit.
Example:
Let’s say here, ITEM = 62
Step 1: ARR[MID] < ITEM : thus END =9 and BEG = MID +1 = 6. Thus our new sub-array is,
Lab Exercise
// Program
#include<stdio.h>
int binarySearch(int[], int, int, int);
void main ()
{
int arr[10] = {10, 12, 21, 23, 40, 48, 50, 78, 90, 96, 100};
int item, location=-1;
printf("Enter the item which you want to search ");
scanf("%d",&item);
}
return -1;
}
Output
1. Linear search is iterative in nature and uses a sequential approach. On the other hand,
Binary search implements a divide and conquer approach.
2. The best-case time in linear search is for the first element, i.e., O (1). As against, in binary
search, it is for the middle element, i.e., O (1).
3. Linear search can be implemented in an array as well as in a linked list, whereas binary
search cannot be implemented directly in a linked list.
4. Linear search is easy to use, and there is no need for any ordered elements. On the other
hand, the binary search algorithm is tricky, and elements are necessarily arranged in
order.
Summary
Search is a programme that allows you to look for papers, files, and other forms of
information. A binary search is a form of advanced search method for finding and retrieving
data from a sorted list of things.
Binary search is commonly known as a half-interval search or a logarithmic search.
A binary search is not suitable for unsorted data.
The linear search is simple to use, or we could say less complex, because the components in
a linear search can be put in any sequence, whereas the elements in a binary search must be
arranged in a specific order.
The implementation of binary search is limited as it can be implemented only on those data
structures that have two-way traversal.
In a linear search, the worst- case scenario for finding the element is O(n).
Keywords
Searching:Searching in data structure refers to the process of finding location LOC of an element in
a list.
Linear Search: This is the traditional technique for searching an element in a collection of elements.
In this type of search, all the elements of the list are traversed one by one to find if the element is
present in the list or not.
Binary Search: This is a technique to search an element in the list using the divide and conquer
technique. This type of technique is used in the case of sorted lists. Instead of searching an element
one by one in the list, it directly goes to the middle element of the list, divides the array into 2 parts,
and decides element lies in which sub-array the element exists.
Complexity:Complexity of an algorithm is a measure of the amount of time and/or space required
by an algorithm for an input of a given size (n).
Self Assessment
6. Linear search is mostly used to search an unordered list in which the items are not sorted.
A. True
B. False
C. Sometimes true
D. Sometimes false
A. Binary Search
B. Linear Search
C. Both binary search and linear search
D. None of the above
12. Average case complexity and worst case complexity of binary search algorithm are same
A. True
B. False
D. Binary search is a fast search algorithm with a run-time complexity of (log X).
15. Which from the following technique is used for finding a value from an array?
A. Linear Search
B. Binary Search
C. Bubble sort
D. All above
6. A 7. C 8. B 9. B 10. A
Review Questions
1. What is searching? Explain different types of searching in data structure.
2. Differentiate between linear search and binary search.
3. Linear search also known as sequential search. Comment.
4. What is the role of searching in data structure?
5. What are applications of searching?
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Lipschutz. Seymour. Data Structures with C. Delhi: Tata McGraw Hill
Reddy.A.M Padma (2006). Data Structures Using C. Bangalore: Sri Nandi Publications
Greg W Scragg, Genesco Suny, Problem Solving with Computers, Jones and Bartlett, 1997.
R.G. Dromey, Englewood Cliffs, N.J., How to Solve it by Computer, Prentice-Hall
International, 1982.
YashvantKanetkar, Let us C
Web Links
https://www.javatpoint.com/ds-linear-search-vs-binary-search
https://en.wikipedia.org/
https://onlinedegree.iitm.ac.in/
Dr. Prikshat Kumar Angra, Lovely Professional University Unit 14: Sorting
Objectives
After studying this unit, you will be able to:
Understand Sorting
Define sorting algorithms
Analyze sorting techniques
Introduction
Sorting is the process of arranging data in a preferred order in a data structure. Sorting data makes
it easier to swiftly and simply search through it. A dictionary is the most basic example of sorting.
When you wanted to look up a term in a dictionary before the Internet, you had to do it in
alphabetical order. This made things a lot easier.
Imagine the stress of having to sift through a large book containing all of the English words from
around the world in a jumbled sequence! It's the same dread that an engineer will feel if their data
isn't organized and categorized.
Data structures
Sorting is the process of ordering or placing a list of elements from a collection in some
kind of order. It is nothing but the storage of data in sorted order.
Sorting can be done in ascending and descending order.
It arranges the data in a sequence, which makes searching easier.
Output: [h,i,j,k,l,m,n,o]
Sorting Categories
There are two different categories in sorting:
Internal sorting: If the input data is such that it can be adjusted in the main memory at once, it is
called internal sorting.
External sorting: If the input data is such that it cannot be adjusted in the memory entirely at once,
it needs to be stored in a hard disk, floppy disk, or any other storage device. This is called external
sorting.
1. Quick Sort
2. Bubble Sort
3. Merge Sort
4. Insertion Sort
5. Selection Sort
6. Heap Sort
7. Radix Sort
8. Bucket Sort
The diagram represents how bubble sorting actually works. This sort takes O (n2) time. It starts
with the first two elements and sorts them in ascending order.Bubble sort starts with the first two
elements. It compares the elements to check which one is greater.In the above diagram, element 40
is greater than 10, so these values must be swapped. This operation continues until the array is
sorted in ascending order.
Algorithm
bubbleSort( Arr[], totat_elements)
swap(Arr[j], Arr[j+1])
swapped = true
end if
end for
end for
end
Data structures
Lab Exercise:
#include <stdio.h>
void bubble_sort(long [], long);
int main()
{
long array[100], n, c, d, swap;
printf("Enter Elements\n");
scanf("%ld", &n);
printf("Enter %ld integers\n", n);
for (c = 0; c < n; c++)
scanf("%ld", &array[c]);
bubble_sort(array, n);
printf("Sorted list in ascending order:\n");
for ( c = 0 ; c < n ; c++ )
printf("%ld\n", array[c]);
return 0;
}
void bubble_sort(long list[], long n)
{
long c, d, t;
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0 ; d < n - c - 1; d++)
{
if (list[d] > list[d+1])
{
t = list[d];
list[d] = list[d+1];
list[d+1] = t;
}
}
}
}
Output
Data structures
The above diagram represents how insertion sorting works. Insertion sorting works like the way
we sort playing cards in our hands. It always starts with the second element as the key. The key is
to compare it with the elements ahead of it and put it in the right place.In the above figure, 40 has
nothing before it. Element 10 is compared to 40 and is inserted before 40. Element 9 is smaller than
40 and 10, so it is inserted before 10 and this operation continues until the array is sorted in
ascending order.
Algorithm
INSERTION-SORT(A)
for i = 1 to n
key ← A [i]
j←i –1
while j > = 0 and A[j] > key
A[j+1] ← A[j]
j←j –1
End while
A[j+1] ← key
End for
Lab Exercise
#include <stdio.h>
int main()
{
int n, array[1000], c, d, t;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
{
scanf("%d", &array[c]);
}
for (c = 1 ; c <= n - 1; c++)
{
d = c;
while ( d > 0 && array[d] < array[d-1])
{
t = array[d];
array[d] = array[d-1];
array[d-1] = t;
d--;
}
}
printf("Sorted list in ascending order:\n");
for (c = 0; c <= n - 1; c++)
{
printf("%d\n", array[c]);
}
return 0;
}
Output
We perform the steps given below until the unsorted subarray becomes empty:
Data structures
In the above diagram, the smallest element is found in first pass that is 9 and it is placed at the first
position. In second pass, smallest element is searched from the rest of the element excluding first
element. Selection sort keeps doing this, until the array is sorted.
Lab Exercise
#include <stdio.h>
int main()
{
int array[100], n, c, d, position, swap;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for ( c = 0 ; c < n ; c++ )
scanf("%d", &array[c]);
for ( c = 0 ; c < ( n - 1 ) ; c++ )
{
position = c;
for ( d = c + 1 ; d < n ; d++ )
{
if ( array[position] > array[d] )
position = d;
}
if ( position != c )
{
swap = array[c];
array[c] = array[position];
array[position] = swap;
}
}
printf("Sorted list in ascending order:\n");
Lab Exercise
#include <stdio.h>
void shellsort(int arr[], int num)
{
int i, j, k, tmp;
for (i = num / 2; i > 0; i = i / 2)
{
for (j = i; j < num; j++)
{
for(k = j - i; k >= 0; k = k - i)
{
if (arr[k+i] >= arr[k])
Data structures
break;
else
{
tmp = arr[k];
arr[k] = arr[k+i];
arr[k+i] = tmp;
}
}
}
}
}
int main()
{
int arr[30];
int k, num;
printf("Enter total no. of elements : ");
scanf("%d", &num);
printf("\nEnter %d numbers: ", num);
for (k = 0 ; k < num; k++)
{
scanf("%d", &arr[k]);
}
shellsort(arr, num);
printf("\n Sorted array is: ");
for (k = 0; k < num; k++)
printf("%d ", arr[k]);
return 0;
}
Output
Algorithm
Step 1: [INITIALIZE] SET I = BEG, J = MID + 1, INDEX = 0
Step 2: Repeat while (I <= MID) AND (J<=END)
IF ARR[I] < ARR[J]
SET TEMP[INDEX] = ARR[I]
SET I = I + 1
ELSE
SET TEMP[INDEX] = ARR[J]
SET J = J + 1
[END OF IF]
SET INDEX = INDEX + 1
[END OF LOOP]
Step 3: [Copy the remaining
elements of right sub-array, if
any]
Data structures
IF I > MID
Repeat while J <= END
SET TEMP[INDEX] = ARR[J]
SET INDEX = INDEX + 1, SET J = J + 1
[END OF LOOP]
[Copy the remaining elements of
left sub-array, if any]
ELSE
Repeat while I <= MID
SET TEMP[INDEX] = ARR[I]
SET INDEX = INDEX + 1, SET I = I + 1
[END OF LOOP]
[END OF IF]
Step 4: [Copy the contents of TEMP back to ARR] SET K = 0
Step 5: Repeat while K < INDEX
SET ARR[K] = TEMP[K]
SET K = K + 1
[END OF LOOP]
Step 6: Exit
Lab Exercise
#include<stdio.h>
void mergeSort(int[],int,int);
void merge(int[],int,int,int);
void main ()
{
int a[10]= {12, 9,8, 25, 23, 44, 62, 78, 34, 23};
int i;
mergeSort(a,0,9);
printf("printing the sorted elements");
for(i=0;i<10;i++)
{
printf("\n%d",a[i]);
}
}
void mergeSort(int a[], int beg, int end)
{
int mid;
if(beg<end)
{
mid = (beg+end)/2;
mergeSort(a,beg,mid);
mergeSort(a,mid+1,end);
merge(a,beg,mid,end);
}
}
void merge(int a[], int beg, int mid, int end)
{
int i=beg,j=mid+1,k,index = beg;
int temp[10];
while(i<=mid && j<=end)
{
if(a[i]<a[j])
{
temp[index] = a[i];
i = i+1;
}
else
{
temp[index] = a[j];
j = j+1;
}
index++;
}
if(i>mid)
{
while(j<=end)
{
temp[index] = a[j];
index++;
j++;
}
}
else
{
while(i<=mid)
{
temp[index] = a[i];
Data structures
index++;
i++;
}
}
k = beg;
while(k<index)
{
a[k]=temp[k];
k++;
}
}
Output
Lab Exercise
#include <stdio.h>
int largest(int a[]);
void radix_sort(int a[]);
void main()
{
int i;
int a[10]={90,23,101,45,65,23,67,89,34,23};
radix_sort(a);
Data structures
i++;
}
}
divisor *= 10;
}
}
Output
BASIS FOR
INSERTION SORT SELECTION SORT
COMPARISON
BASIS FOR
INSERTION SORT SELECTION SORT
COMPARISON
Summary
A Sorting Algorithm is used to rearrange a given array or list elements according to a
comparison operator on the elements.
Internal sorting: If the input data is such that it can be adjusted in the main memory at once,
it is called internal sorting.
Data structures
External sorting: If the input data is such that it cannot be adjusted in the memory entirely at
once, it needs to be stored in a hard disk, floppy disk, or any other storage device. This is
called external sorting.
Selection sort is a simple comparison-based sorting algorithm. It is in-place and needs no
extra memory.
Keywords
Merge sort is a good choice if you want a stable sorting algorithm. Also, merge sort can
easily be extended to handle data sets that can't fit in RAM, where the bottleneck cost is
reading and writing the input on disk, not comparing and swapping individual items.
Radix sort looks fast, with its O(n)O(n) worst-case time complexity. But, if you're using it to
sort binary numbers, then there's a hidden constant factor that's usually 32 or 64 (depending
on how many bits your numbers are). That's often way bigger than O(\lg(n))O(lg(n)),
meaning radix sort tends to be slow in practice.
Merge Sort - Merge sort (also commonly spelled mergesort) is an efficient, general-purpose,
comparison-based sorting algorithm.
Heap Sort- heapsort is a comparison-based sorting algorithm. Heapsort can be thought of as
an improved selection sort: like that algorithm, it divides its input into a sorted and an
unsorted region, and it iteratively shrinks the unsorted region by extracting the largest
element and moving that to the sorted region.
Sorting: Sorting is the technique of arranging the data elements in some logical order, either
ascending or descending order. Some algorithms make use of sorted lists. Therefore,
efficient sorting is essential for optimizing these algorithms to ensure that they work
correctly.
Internal sorting: If the input data is such that it can be adjusted in the main memory at once,
it is called internal sorting.
External sorting: If the input data is such that it cannot be adjusted in the memory entirely
at once, it needs to be stored in a hard disk, floppy disk, or any other storage device. This is
called external sorting.
Self Assessment
1. Selection sort is a simple sorting algorithm which finds the smallest element in the array and
exchanges it with the element in the first position.
A. True
B. False
C. Sometimes true
D. Sometimes false
C. O(n)
D. O(n2)
Data structures
15. Insertion sort sorting method sorts the array by shifting elements one by one.
A. True
B. False
6. A 7. A 8. A 9. B 10. A
Review Questions
1. What is sorting? How it is different from searching.
2. Discuss the advantages of using sorting in the data structure.
3. Differentiate between selection sort and merge sort.
4. Write a program that demonstrates the working of merge sort.
5. Write a program that demonstrates the working of selection sort.
6. Write a program that demonstrates the working of bubble sort.
7. Differentiate between insertion sort and selection sort.
8. Write and explain insertion sort algorithm. What is the complexity of the algorithm?
Further Readings
Books Ashok N. Kamthane, “Programming with ANCI & Turbo C”, Pearson Education,
Year of Publication, 2008
Web Links
https://www.geeksforgeeks.org/sorting-
algorithms/https://betterexplained.com/articles/sorting-algorithms/