Notes of Data structure
What is Data Structure:
A data structure is a way of organizing, managing, and storing data in a computer so
that it can be used efficiently.A data structure not only stores the data but also defines
the relationship between data elements and the operations that can be performed on
them.
Operations of Data structure:
In simple terms, it’s a container that holds data in a specific format to make different
operations (like searching, inserting, deleting, and sorting) easier and faster.
Explanation of data structure:
Every program in computer science deals with large amounts of data — such as
numbers, names, lists, or [Link] process that data efficiently, we need to arrange it
properly. This arrangement is called a data structure.
For example:
1)If you have a list of student names, you can store them in an array.
2)If you need to access them alphabetically, you might use a tree structure.
3)If you want to search and access data quickly, a hash table may be better.
Each data structure has its own advantages, disadvantages, and use cases depending
on the type of operation you want to perform.
Types of Data Structures:
Data structures are mainly divided into two categories:
1. Linear Data Structures
Data elements are arranged in a sequential order, where each element is connected to
the previous and next one.
Examples:
Array: Fixed-size structure; stores elements of the same type.
Linked List: Dynamic size; elements (nodes) linked through pointers.
Stack: Follows LIFO (Last In, First Out) principle.
Queue: Follows FIFO (First In, First Out) principle.
2. Non-Linear Data Structures
Data elements are not arranged sequentially; they form a hierarchical or
interconnected relationship.
Examples:
Tree: Hierarchical data representation (used in file systems, databases).
Graph: Network-like connections (used in social networks, GPS systems, etc.).
Purpose of Data Structures
The main purpose of data structures is to:
Organize and store data efficiently. So that it can be easily accessed and modified.
2)Improve performance of operations.
Efficient data structures reduce time and space complexity.
3)Facilitate data management.
Helps handle large and complex data easily.
4)Enable reusability and abstraction.
Once designed, a data structure can be reused in different programs.
5)Support complex algorithms.
Many algorithms (like searching, sorting, graph traversal) depend on suitable data
structures.
Applications of Data Structures:
Data structures are used in almost every field of computer science.
Here are some practical applications:
1. Arrays:
Used for storing multiple items of the same type.
Example: Storing marks of students, storing pixel data of an image.
2. Linked Lists:
Used in dynamic memory allocation, undo functionality, and navigation systems.
Example: Music playlist (next/previous song).
3. Stacks:
Used in function calls, expression evaluation, syntax checking.
Example: Undo/redo operations in text editors.
4. Queues:
Used in scheduling and resource management.
Example: Printer queue, CPU task scheduling.
5. Trees:
Used for hierarchical data representation.
Example: XML/HTML DOM, file systems, databases.
6. Graphs:
Used to represent networks.
Example: Social networks (Facebook friends), GPS navigation routes.
7. Hash Tables:
Used for fast data retrieval using key-value pairs.
Example: Password storage, database indexing.
Benefits of Using Data Structures
1)Efficiency: Reduces the time to perform operations like search, insert, and delete.
2)Reusability: Can be used in multiple programs or systems.
3)Data Management: Handles large data sets systematically.
4)Scalability: Supports complex applications like operating systems and databases.
5)Optimization: Reduces both memory and computational costs.
Q)Different between linear and non linear data structure?
Linear Non linear
1)Data elements are arranged in a Data elements are arranged in a
sequential order (one after another) hierarchical or interconnected way.
2)Traversal is simple because elements Traversal is complex since multiple
are visited in a single run (one by one). paths or branches exist.
3)Each element is connected to only its Each element can be connected to many
previous and next element. other elements.
4)Stored mostly in continuous memory Stored mostly in non-continuous
locations. memory locations using pointers.
5)Easier to implement and manage due to Harder to implement because of
simple structure. complex relationships.
6)Examples: Arrays, Linked Lists, Stacks, Examples: Trees, Graphs.
Queues.
7)Time complexity for searching or Time complexity can be lower with
accessing elements is usually higher (like efficient structures (like binary trees).
linear search).
What is an Array?
An array is a collection of similar data elements stored at contiguous (continuous)
memory [Link] elements in an array are of the same data type (e.g., all integers,
all characters, etc.), and each element can be accessed using its index.
Simple Definition:
An array is a data structure that stores multiple values of the same type under a single
variable name.
Example:
int marks[5] = {80, 85, 90, 70, 75};
1) marks is the name of the array.
2) [5] means it can hold 5 integer values.
3) {80, 85, 90, 70, 75} are the elements.
4) Indexes start from 0 → so marks[0] = 80, marks[4] = 75
Types of Arrays
Arrays can be of one, two, or three dimensions (1D, 2D, 3D).
1D Array (One-Dimensional Array)
Definition:
A 1D array is the simplest form of an array.
It represents a list of elements arranged in a single row or column.
Example:
int marks[5] = {80, 85, 90, 70, 75};
Index 0 1 2 3 4
Value 80 85 90 70 75
Use Case:
Used to store lists such as names, marks, prices, or IDs.
Accessing Elements:
marks[2] → returns 90
Length of the 1D Array:
BA= 100 102 104 106 108
1 2 3 4 5
Index= 0 1 2 3 4
LB UB
Size = 2
Now
LB = 0 , UB = 4 then length?
Length=UB-IB+1
= 4-0+1
=5
Address of a 1D array?
Find Address of Index 3:
Adress=BA + Index * Size
= 100+3*2
= 106
2D Array (Two-Dimensional Array)
Definition:
A 2D array is an array of arrays, meaning it stores data in rows and columns — just
like a table or matrix.
Example:
int matrix[2][3] = {
{1, 2, 3},
{4, 5, 6}
};
Row /column 0 1 2
0 1 2 3
1 4 5 6
Use Case:
Used for matrices, tables, game boards, images, etc.
Accessing Elements:
matrix[1][2] → returns 6
2D Array
BA= 100 102 103 104
00 01 02 03
11 12 13 14
20 21 22 23
length of 2D array
=row *column = 3*4= 12
Size = 1
Address of 2D array?
By Row major order:
BA=100 101 102 103 104 105 106 107 108 109 110 111
00 01 02 03 10 11 12 13 20 21 22 23
A[i][j] = ([I*column+j]*Size+BA)
A[2][1]=([2*4+1]*1+100)
=8+1*1+100
=9+100
=109
3D Array (Three-Dimensional Array)
Definition:
A 3D array is an array of 2D arrays — it adds another dimension (depth or layer).
It can be imagined as a cube of data with rows, columns, and depth.
Example:
int cube[2][2][3] = {
{ {1, 2, 3}, {4, 5, 6} },
{ {7, 8, 9}, {10, 11, 12} }
};
Here:
There are 2 layers,
Each layer has 2 rows and 3 columns.
Use Case:
Used in 3D graphics, scientific simulations, geographical maps, etc.
Accessing Elements:
cube[1][0][2] → returns 9
Operation of Arrays
Traversal Algorithm
Purpose: To visit or access each element of the array one by one.
Algorithm:
step 1: Start
step 2: Set K = 0
step 3: Repeat steps 4 and 5 while K < n
step 4: Display A[K]
step5: Increment K = K + 1
Step 6: Stop
Example: For array A = [10, 20, 30], output → 10, 20, 30
2. Insertion Algorithm
Purpose: To insert a new element at a given position (index).
Algorithm:
Step 1:Start
Step 2: Set i = n - 1 // last element
Step 3: Repeat steps 4 and 5 while i >= position
Step 4: A[i + 1] = A[i] // shift elements right
Step 5: Decrease i = i - 1
Step 6: A[position] = item // insert new value
Step 7: n = n + 1Step 8: Stop
Example:
A = [10, 20, 30, 40], insert 25 at position 2
→ [10, 20, 25, 30, 40]
3. Deletion Algorithm
Purpose: To delete an element from a given position.
Algorithm:
Step 1: Start
Step 2: Set i = position
Step 3: Repeat steps 4 and 5 while i < n - 1
Step 4: A[i] = A[i + 1] // shift left
Step 5: i = i + 1
Step 6: n = n - 1
Step 7: Stop
Example:
A = [10, 20, 30, 40], delete element at position 1
→ [10, 30, 40]
4. Searching Algorithm
A. Linear Search
Purpose: To find an element in the array by checking each element one by one.
Algorithm:
Step 1: Start
Step 2: Set i = 0
Step 3: Repeat steps 4 and 5 while i < n
Step 4: If A[i] == item, then print "Found at position i" and Stop
Step 5: i = i + 1
Step 6: If i == n, print "Not Found"
Step 7: Stop
B. Binary Search (for Sorted Array)
Agorithm:
Step 1: Start
Step 2: Set low = 0, high = n - 1
Step 3: Repeat while low <= high
Step 4: mid = (low + high) / 2
Step 5: If A[mid] == item, print "Found" and Stop
Step 6: If item < A[mid], set high = mid - 1
Step 7: Else set low = mid + 1
Step 8: Stop (if not found)
Updating Algorithm
Purpose: To modify the value of an element at a specific index.
Algorithm:
Step 1: Start
Step 2: Read index position and new_value
Step 3: A[position] = new_value
Step 4: Stop
Example:
A = [10, 20, 30], update position 1 → 50
Result: [10, 50, 30]
5. Sorting Algorithm (Bubble Sort)
Purpose: To arrange elements in ascending order.
Algorithm:
Step 1: Start
Step 2: For i = 0 to n-1
Step 3: For j = 0 to n-i-1
Step 4: If A[j] > A[j+1], then swap A[j] and A[j+1]
Step 5: End inner loop
Step 6: End outer loop
Step 7: Stop
Example:
Before: [30, 10, 20] → After: [10, 20, 30]
Big O Notation:
Definition:
Big O Notation is a mathematical way to describe how the running time or space of an
algorithm grows as the size of the input (n) [Link] helps to measure the
efficiency of an algorithm especially when dealing with large data.
Simple Example:
1)Suppose you have to check each student’s marks in a [Link] there are n students,
you will check n times →Time complexity = O(n) (linear time).
2)But if you only check one student’s marks, no matter how many students there are
→Time complexity = O(1) (constant time).
Common Big O Notations:
Big O Name Description Example
O(1) Constant Time Time never changes with Accessing an
input size element
O(n) Linear Time Time grows directly with Checking all
input students
O(log n) Logarithmic Time grows slowly with
Time input
]O(n²) Quadratic Time grows very fast Nested loops
Time
O(n log n) Log-linear Common in efficient Merge sort
Time sorting
What is a Linked List?
A Linked List is a linear data structure in which elements (called nodes) are connected
using pointers.
Each node contains two parts:
1)Data → The actual value (like 10, 20, 30, etc.)
2)Pointer (next) → The address or reference to the next node in the list
Unlike arrays, linked lists are not stored in contiguous memory locations — they are
connected through pointers.
Purpose / Applications of Linked List
1)Dynamic memory allocation (size can grow/shrink at runtime)
2)Implement stacks, queues, and graphs
3)Useful in memory management systems
4)Insertion and deletion operations are easier (no shifting like arrays)
Types of link listed(LL):
Data → stores the value
Pointer(s) → stores address of the next (and sometimes previous) node
1. Singly Linked List (SLL)
Definition:
A Singly Linked List is a type of linked list in which each node contains data and a
pointer to the next node.
The last node points to NULL (indicating the end of the list).
Structure of Node:
struct Node {
int data;
Node* next;
};
Diagram:
[10 | *] → [20 | *] → [30 | NULL]
Explanation:
1)Each node has one pointer (next).
2)Traversal is only in one direction (from head to end).
3)Simple and memory efficient.
Example:
Suppose we create a linked list with values 10 → 20 → 30
1)Head points to the first node (10).
2)10’s next → 20
3)20’s next → 30
4)30’s next → NULL
So:
Head → 10 → 20 → 30 → NULL
Advantages:
1)Easy to implement
2)Efficient insertion and deletion at beginning
Disadvantages:
1)Cannot traverse backward
2)Random access not possible (must go sequentially)
2. Doubly Linked List (DLL)
Definition:
A Doubly Linked List is a list in which each node contains three parts:
1)Pointer to the previous node
2)Data
3)Pointer to the next node
Structure of Node:
struct Node {
Node* prev;
int data;
Node* next;
};
Diagram:
NULL ← [ | 10 | ] ↔ [ | 20 | ] ↔ [ | 30 | ] → NULL
Explanation:
1)Each node connects both forward and backward.
2)Traversal possible in both directions.
3)Easier deletion because you can go backward too.
Example:
Let’s create list → 10 ↔ 20 ↔ 30
10’s prev = NULL, next = 20
20’s prev = 10, next = 30
30’s prev = 20, next = NULL
NULL ← 10 ↔ 20 ↔ 30 → NULL
Advantages:
1)Can traverse in both directions
2)Easier deletion of any node
Disadvantages:
1)Extra memory for storing prev pointer
2)More complex insertion/deletion logic
3. Circular Singly Linked List (CSLL)
Definition:
A Circular Linked List is like a singly linked list, but the last node’s next pointer
points back to the first node, forming a circle.
Structure of Node:
struct Node {
int data;
Node* next;
};
Diagram:
[10 | *] → [20 | *] → [30 | *] ↺
↑________________________|
Explanation:
1)There is no NULL at the end.
2)The last node points back to the first node.
3)Can be traversed infinitely unless you stop manually.
Example:
10 → 20 → 30 → (back to 10)
Traversal:
Head = 10 → 20 → 30 → 10 → 20 → …
Advantages:
1)Can move in a loop continuously
2)Easier to implement queues or round-robin scheduling
Disadvantages:
1)Difficult to detect the end of the list
2)Risk of infinite loop if not careful
4. Circular Doubly Linked List (CDLL)
Definition:
A Circular Doubly Linked List combines both:
1)Circular feature (last node connects to first)
2)Doubly feature (each node has prev and next)
Structure of Node:
struct Node {
Node* prev;
int data;
Node* next;
};
Diagram:
↺ 10 ↔ 20 ↔ 30 ↔ (back to 10)
Explanation:
1)Last node’s next points to first node.
2)First node’s prev points to last node.
3)Traversal possible in both directions circularly
Example:
List: 10 ↔ 20 ↔ 30
10’s prev = 30, next = 20
20’s prev = 10, next = 30
30’s prev = 20, next = 10
(Circular and Bidirectional)
Advantages:
1)Can go forward or backward endlessly
2)Useful in navigation systems or playlist loops
Disadvantages:
1)Complex to manage pointers
2)More memory usage
Insertion in Linked List
Insertion means adding a new node in the list.
There are generally three types of insertions (for singly linked list):
1) Insertion at the Beginning
1)Create a new node.
2)Point its next to the current head.
3)Update head to this new node.
Algorithm:
Step 1: Create newNode
Step 2: newNode → data = value
Step 3: newNode → next = head
Step 4: head = newNode
2) Insertion at the End
1)Create a new node.
2)Traverse to the last node.
3)Change last node’s next to the new node.
4)New node’s next = NULL.
Algorithm:
Step 1: Create newNode
Step 2: newNode → data = value
Step 3: newNode → next = NULL
Step 4: temp = head
Step 5: While (temp → next != NULL)
temp = temp → next
Step 6: temp → next = newNode
3) Insertion in the Middle / Specific Position
1)Traverse to the node after which new node will be inserted.
2)Set newNode’s next to the next of that node.
3)Set that node’s next to newNode.
Algorithm:
Step 1: Create newNode
Step 2: newNode → data = value
Step 3: temp = head
Step 4: Traverse to position (pos - 1)
Step 5: newNode → next = temp → next
Step 6: temp → next = newNode
Memory representation in Array?
Definition:
Memory representation in an array means how array elements are stored in the
computer’s memory (RAM).
An array stores elements in contiguous (continuous) memory locations — that means
each element is placed right next to the previous one in memory.
Example (1D Array)
Let’s say you have an array:
int A[5] = {10, 20, 30, 40, 50};
If he base address of A[0] is 1000, and each integer takes 4 bytes,
then memory is stored like this
Element Value Address
A[0] 10 1000
A[1] 20 1004
A[2] 30 1006
A[3] 40 1008
A[4] 50 1010
Formula (1D Array):
Address of A[i] = Base Address + (i × Size of Each Element)
Address of A[2] = 1000 + (2 × 4) = 1008
2D Array Memory Representation
A 2D array is like a table of rows and columns.
Example:
int A[2][3] = {
{10, 20, 30},
{40, 50, 60}
};
Memory is still contiguous but how it is arranged depends on row-major or column-
major order.
1. Row-Major Order (C/C++ Default)
All elements of the first row are stored first, then the second row, and so on.
Order in memory Elements
A[0][1],A[0][2],A[1][0],A[1][1],A[1][2] 10,20,30,40,50,60
Formula (Row-Major Order):
Address(A[i][j]) = Base + [ (i × Total_Columns) + j ] × Element_Size
➡ Example:
Base = 1000, Total_Columns = 3, Element_Size = 4 bytes
Find address of A[1][2]:
= 1000 + [ (1×3) + 2 ] × 4 = 1000 + (5×4) = 1020
2. Column-Major Order
All elements of the first column are stored first, then the second column, etc.
Order in memory Elements
A[0][1],A[0][2],A[1][0],A[1][1],A[1][2] 10,20,30,40,50,60
Formula (Column-Major Order):
Address(A[i][j]) = Base + [ (j × Total_Rows) + i ] × Element_Size
➡ Example:
Base = 1000, Total_Rows = 2, Element_Size = 4
Find address of A[1][2]:
= 1000 + [ (2×2) + 1 ] × 4 = 1000 + (5×4) = 1020
address of A[2] = 1000 + (2 × 4) = 1008
3D Array Memory Representation
Definition:
A 3D array stores data in three dimensions — like a cube of elements.
For example:
int A[2][3][4];
means
2 planes (or layers)
each plane has 3 rows
each row has 4 columns
So total elements = 2 × 3 × 4 = 24.
How is 3D Array Stored in Memory?
Even though it looks like a cube, in memory it is stored linearly (contiguously) — just
like 1D and 2D arrays.
So the compiler flattens this cube into a single continuous block of memory.
1. Row-Major Order (used in C/C++)
Formula:
Address (A[i][j][k]) = Base Address + [ (i × (Y × Z)) + (j × Z) + k ] × Size
Where:
i = index of plane
j = index of row
k = index of column
Y = total number of rows
Z = total number of columns
Size = bytes per element
Example:
Let’s assume:
int A[2][3][4];
and base address = 1000,
size of each integer = 4 bytes
We need address of A[1][2][3]
Here,
i=1
j=2
k=3
Y=3
Z=4
Plug in formula:
Address = 1000 + [ (1 × (3×4)) + (2×4) + 3 ] × 4
Address = 1000 + [ (12) + (8) + 3 ] × 4
Address = 1000 + (23 × 4)
Address = 1000 + 92
Address = 1092
Address of A[1][2][3] = 1092