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

DS UNIT 1 NOTES

The document provides an introduction to linear data structures in computer science, detailing their characteristics, types (arrays, linked lists, stacks, and queues), and operations. It also explains abstract data types, search algorithms (linear and binary), and sorting algorithms (insertion and selection sort), including their complexities. Each data structure and algorithm is accompanied by definitions, features, and example code implementations.

Uploaded by

nothingnameis4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

DS UNIT 1 NOTES

The document provides an introduction to linear data structures in computer science, detailing their characteristics, types (arrays, linked lists, stacks, and queues), and operations. It also explains abstract data types, search algorithms (linear and binary), and sorting algorithms (insertion and selection sort), including their complexities. Each data structure and algorithm is accompanied by definitions, features, and example code implementations.

Uploaded by

nothingnameis4
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 21

UNIT-I

INTRODUCTION TO LINEAR DATA STRUCTURES

Introduction to Linear Data Structures


Linear Data Structures are a type of data structure in computer science where data elements are arranged sequentially or linearly.
Each element has a previous and next adjacent, except for the first and last elements.

Characteristics of Linear Data Structure:


 Sequential Organization: In linear data structures, data elements are arranged sequentially, one after the other. Each
element has a unique predecessor (except for the first element) and a unique successor (except for the last element)
 Order Preservation: The order in which elements are added to the data structure is preserved. This means that the first
element added will be the first one to be accessed or removed, and the last element added will be the last one to be
accessed or removed.
 Fixed or Dynamic Size: Linear data structures can have either fixed or dynamic sizes. Arrays typically have a fixed size
when they are created, while other structures like linked lists, stacks, and queues can dynamically grow or shrink as
elements are added or removed.
 Efficient Access: Accessing elements within a linear data structure is typically efficient. For example, arrays offer
constant-time access to elements using their index.

Linear data structures are commonly used for organising and manipulating data in a sequential fashion. Some of the most
common linear data structures include:
 Arrays: A collection of elements stored in contiguous memory locations.
 Linked Lists: A collection of nodes, each containing an element and a reference to the next node.
 Stacks: A collection of elements with Last-In-First-Out (LIFO) order.
 Queues: A collection of elements with First-In-First-Out (FIFO) order.

Abstract Data Types


An Abstract Data Type (ADT) is a conceptual model that defines a set of operations and behaviors for a data structure, without
specifying how these operations are implemented or how data is organized in memory. The definition of ADT only mentions
what operations are to be performed but not how these operations will be implemented. It does not specify how data will be
organized in memory and what algorithms will be used for implementing the operations. It is called “abstract” because it provides
an implementation-independent view.
The process of providing only the essentials and hiding the details is known as abstraction.
1. Array :

An array is a collection of items of same data type stored at contiguous memory locations.

Characteristics of Array Data Structure:

Homogeneous Elements: All elements within an array must be of the same data type.
Contiguous Memory Allocation: In most programming languages, elements in an array are stored in contiguous (adjacent)
memory locations.
Zero-Based Indexing: In many programming languages, arrays use zero-based indexing, which means that the first element is
accessed with an index of 0, the second with an index of 1, and so on.
Random Access: Arrays provide constant-time (O(1)) access to elements. This means that regardless of the size of the array, it
takes the same amount of time to access any element based on its index.

2. Linked List

A Linked List is a linear data structure which looks like a chain of nodes, where each node contains a data field and a
reference(link) to the next node in the list. Unlike Arrays, Linked List elements are not stored at a contiguous location.
Common Features of Linked List:
 Node: Each element in a linked list is represented by a node, which contains two components:
o Data: The actual data or value associated with the element.
o Next Pointer(or Link): A reference or pointer to the next node in the linked list.
 Head: The first node in a linked list is called the “head.” It serves as the starting point for traversing the list.
 Tail: The last node in a linked list is called the “tail.”

Types of Linked Lists:


 Singly Linked List: In this type of linked list, every node stores the address or reference of the next node in the list and
the last node has the next address or reference as NULL. For example: 1->2->3->4->NULL

 Doubly Linked Lists: In a doubly linked list, each node has two pointers: one pointing to the next node and one
pointing to the previous node. This bidirectional structure allows for efficient traversal in both directions.

 Circular Linked Lists: A circular linked list is a type of linked list in which the first and the last nodes are also
connected to each other to form a circle, there is no NULL at the end.
3. Stack:
Stack is a linear data structure that follows LIFO (Last In First Out) Principle, the last element inserted is the first to be popped
out. It means both insertion and deletion operations happen at one end only.
Linear Search Algorithm (Sequential Search)

Types of Stack:
 Fixed Size Stack : As the name suggests, a fixed size stack has a fixed size and cannot grow or shrink dynamically. If
the stack is full and an attempt is made to add an element to it, an overflow error occurs. If the stack is empty and an
attempt is made to remove an element from it, an underflow error occurs.
 Dynamic Size Stack : A dynamic size stack can grow or shrink dynamically. When the stack is full, it automatically
increases its size to accommodate the new element, and when the stack is empty, it decreases its size. This type of stack
is implemented using a linked list, as it allows for easy resizing of the stack.

Basic Operations on Stack:


In order to make manipulations in a stack, there are certain operations provided to us.
 push() to insert an element into the stack
 pop() to remove an element from the stack
 top() Returns the top element of the stack.
 isEmpty() returns true if stack is empty else false.
 isFull() returns true if the stack is full else false.

4. Queue Data Structure:


A queue is a linear data structure that follows the First-In-First-Out (FIFO) principle. In a queue, the first element added is the
first one to be removed.

Queue Operations:
 Enqueue(): Adds (or stores) an element to the end of the queue..
 Dequeue(): Removal of elements from the queue.
 Peek() or front(): Acquires the data element available at the front node of the queue without deleting it.
 rear(): This operation returns the element at the rear end without removing it.
 isFull(): Validates if the queue is full.
 isNull(): Checks if the queue is empty.

What is Search?
Search is a process of finding a value in a list of values. In other words, searching is the process of locating given value position
in a list of values.

Linear Search Algorithm (Sequential Search Algorithm)


 Linear search algorithm finds given element in a list of elements with O(n) time complexity where n is
total number of elements in the list.
 This search process starts comparing of search element with the first element in the list.
 If both are matching then results with element found otherwise search element is compared with next
element in the list.
 If both are matched, then the result is "element found". Otherwise, repeat the same with the next element in the list
until search element is compared with last element in the list.
 if that last element also doesn't match, then the result is "Element not found in the list". That means, the search
element is compared with element by element in the list.

Linear search is implemented using following steps...

Step 1: Read the search element from the user


Step 2: Compare, the search element with the first element in the list.
Step 3: If both are matching, then display "Given element found!!!" and terminate the function

Step 4: If both are not matching, then compare search element with the next element in the list.

Step 5: Repeat steps 3 and 4 until the search element is compared with the last element in the list.

Step 6: If the last element in the list is also doesn't match, then display "Element not found!!!" and terminate the function.

Example
Consider the following list of element and search element...
Program:
#include<stdio.h> #include<conio.h>

void main(){
int list[20],size,i,sElement;

printf("Enter size of the list: ");


scanf("%d",&size);

printf("Enter any %d integer values: ",size); for(i = 0; i <


size; i++)
scanf("%d",&list[i]);

printf("Enter the element to be Search: ");


scanf("%d",&sElement);

// Linear Search Logic for(i


= 0; i < size; i++)
{
if(sElement == list[i])
{
printf("Element is found at %d index", i); break;
}
}
if(i == size)
printf("Given element is not found in the list!!!"); getch();
}

Time and Space Complexity of Linear Search Algorithm:


Time Complexity:
 Best Case: In the best case, the key might be present at the first index. So the best case complexity is O(1)
 Worst Case: In the worst case, the key might be present at the last index i.e., opposite to the end from which the search
has started in the list. So the worst-case complexity is O(N) where N is the size of the list.
 Average Case: O(N)
Auxiliary Space: O(1) as except for the variable to iterate through the list, no other variable is used.

------------------------------------------------------------------------------------------------------------------------------------------

Binary Search Algorithm

What is Search?
Search is a process of finding a value in a list of values. In other words, searching is the process of locating given value position
in a list of values.

Binary Search Algorithm


 Binary search algorithm finds given element in a list of elements with O(log n) time complexity where n is total
number of elements in the list.
 The binary search algorithm can be used with only sorted list of element.
 That means, binary search can be used only with list of element which are already arraged in a order.
 The binary search can not be used for list of element which are in random order.
 This search process starts comparing of the search element with the middle element in the list.
 If both are matched, then the result is "element found". Otherwise, we check whether the search element is smaller or
larger than the middle element in the list.
 If the search element is smaller, then we repeat the same process for left sublist of the middle element.
 If the search element is larger, then we repeat the same process for right sublist of the middle element.
 We repeat this process until we find the search element in the list or until we left with a sublist of only one element.
And if that element also doesn't match with the search element, then the result is "Element not found in the list".

Binary search is implemented using following steps... Step 1: Read the

search element from the user

Step 2: Find the middle element in the sorted list


Step 3: Compare, the search element with the middle element in the sorted list.
Step 4: If both are matching, then display "Given element found!!!" and terminate the function
Step 5: If both are not matching, then check whether the search element is smaller or larger than middle element.
Step 6: If the search element is smaller than middle element, then repeat steps 2, 3, 4 and 5 for the left sublist of the middle
element.
Step 7: If the search element is larger than middle element, then repeat steps 2, 3, 4 and 5 for the right sublist of the middle
element.
Step 8: Repeat the same process until we find the search element in the list or until sublist contains only one element.
Step 9: If that element also doesn't match with the search element, then display "Element not found in the list!!!" and terminate the
function.
Example:
Program:
#include<stdio.h> #include<conio.h>

void main()
{
int first, last, middle, size, i, sElement, list[100]; clrscr();

printf("Enter the size of the list: "); scanf("%d",&size);

printf("Enter %d integer values in Assending order\n", size); for (i = 0; i <

size; i++)
scanf("%d",&list[i]);

printf("Enter value to be search: "); scanf("%d",


&sElement);

first = 0;
last = size - 1;
middle = (first+last)/2;

while (first <= last) {


if (list[middle] < sElement) first =
middle + 1;
else if (list[middle] == sElement) { printf("Element found at
index %d.\n",middle); break;
}
else
last = middle - 1;

middle = (first + last)/2;


}
if (first > last)
printf("Element Not found in the list."); getch();
}

Time and Space complexity of Binary Search:


Time Complexityh: O(log n)
Space Complexity: O(1)
------------------------------------------------------------------------------------------------------------------------------------------
Insertion Sort
Sorting is the process of arranging a list of elements in a particular order (Ascending or Descending).
 Insertion sort algorithm arranges a list of elements in a particular order. In insertion sort algorithm, every iteration
moves an element from unsorted portion to sorted portion until all the elements are sorted in the list.

Step by Step Process

The insertion sort algorithm is performed using following steps...


Step 1: Assume that first element in the list is in sorted portion of the list and remaining all elements are in unsorted portion.
Step 2: Consider first element from the unsorted list and insert that element into the sorted list in order specified.
Step 3: Repeat the above process until all the elements from the unsorted list are moved into the sorted list.

Sorting Logic
Following is the sample code for insrtion sort...
//Insertion sort logic
for i = 1 to size-1 { temp =
list[i];
j = i;
while ((temp < list[j]) && (j > 0)) { list[j] =
list[j-1];
j = j - 1;
}
list[j] = temp;
}
Program:

// C program to implement insertion sort


#include <math.h>
#include <stdio.h>

void insertionSort(int arr[], int N) {

// Starting from the second element


for (int i = 1; i < N; i++) {
int key = arr[i];
int j = i - 1;

// Move elements of arr[0..i-1], that are


// greater than key, to one position to
// the right of their current position
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}

// Move the key to its correct position


arr[j + 1] = key;
}
}

int main() {
int arr[] = { 12, 11, 13, 5, 6 };
int N = sizeof(arr) / sizeof(arr[0]);

printf("Unsorted array: ");


for (int i = 0; i < N; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// Calling insertion sort on array arr


insertionSort(arr, N);

printf("Sorted array: ");


for (int i = 0; i < N; i++) {
printf("%d ", arr[i]);
}
printf("\n");

return 0;
}

Output:
Unsorted array: 12 11 13 5 6
Sorted array: 5 6 11 12 13

Complexity of the Insertion Sort Algorithm:

Worst Case : O(n2) Best Case :


Ω(n2) Average Case : Θ(n2)

Selection Sort
 Selection Sort algorithm is used to arrange a list of elements in a particular order (Ascending or
Descending).
 In selection sort, the first element in the list is selected and it is compared repeatedly with remaining all the
elements in the list.
 If any element is smaller than the selected element (for Ascending order), then both are swapped.
Then we select the element at second position in the list and it is compared with remaining all elements in the
list. If any element is smaller than the selected element, then both are swapped. This procedure is repeated till the
entire list is sorted.
Step by Step Process

The selection sort algorithm is performed using following steps...

Step 1: Select the first element of the list (i.e., Element at first position in the list).
Step 2: Compare the selected element with all other elements in the list.
Step 3: For every comparision, if any element is smaller than selected element (for Ascending order), then these two are
swapped.
Step 4: Repeat the same procedure with next position in the list till the entire list is sorted.

Sorting Logic
Following is the sample code for selection sort...

for(i=0; i<size; i++){


for(j=i+1; j<size; j++){ if(list[i] >
list[j])
{
temp=list[i];
list[i]=list[j];
list[j]=temp;
}
}
}
Example:
// C program for implementation of selection sort
#include <stdio.h>

void selectionSort(int arr[], int n) {


for (int i = 0; i < n - 1; i++) {

// Assume the current position holds


// the minimum element
int min_idx = i;

// Iterate through the unsorted portion


// to find the actual minimum
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min_idx]) {

// Update min_idx if a smaller element is found


min_idx = j;
}
}

// Move minimum element to its


// correct position
int temp = arr[i];
arr[i] = arr[min_idx];
arr[min_idx] = temp;
}
}

void printArray(int arr[], int n) {


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

int main() {
int arr[] = {64, 25, 12, 22, 11};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: ");


printArray(arr, n);

selectionSort(arr, n);

printf("Sorted array: ");


printArray(arr, n);

return 0;
}

Output
Original vector: 64 25 12 22 11
Sorted vector: 11 12 22 25 64

Time and Space complexity of Selection Sort:


 Best-case: O(n2), best case occurs when the array is already sorted. (where n is the number of integers in an array)
 Average-case: O(n2), the average case arises when the elements of the array are in a disordered or random order,
without a clear ascending or descending pattern.
 Worst-case: O(n2), The worst-case scenario arises when we need to sort an array in ascending order, but the array is
initially in descending order.

Bubble Sort:
Bubble Sort is a comparison based simple sorting algorithm that works by comparing the adjacent elements and swapping them if
the elements are not in the correct order.

Bubble Sort Algorithm


 Compare and swap the adjacent elements if they are in the wrong order starting from the first two elements.
 Do that for all elements moving from left to right. We will get the largest element at the right end.
 Start compare and swap again from the start but this time, skip the last element as its already at correct position.
 The second last element will be moved at the right end just before the last element.
 Repeat the above steps till all the elements are sorted.

Program:

// C program for implementation of Bubble sort


#include <stdio.h>

void swap(int* arr, int i, int j) {


int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}

void bubbleSort(int arr[], int n) {


for (int i = 0; i < n - 1; i++) {

// Last i elements are already in place, so the loop


// will only num n - i - 1 times
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1])
swap(arr, j, j + 1);
}
}
}

int main() {
int arr[] = { 6, 0, 3, 5 };
int n = sizeof(arr) / sizeof(arr[0]);

// Calling bubble sort on array arr


bubbleSort(arr, n);

for (int i = 0; i < n; i++)


printf("%d ", arr[i]);

return 0;
}

Output
0356

Time and Space complexity of Bubble sort:

Time Complexity:
Best: O(n)
Average: O(n^2)
Worst: O(n^2)

Space Complexity: Worst: O(1)

Basic concept of order of complexity:


Performance analysis of an algorithm is the process of calculating space required by that algorithm and time required by
that algorithm.
Performance analysis of an algorithm is performed by using the following measures...
1).Space required to complete the task of that algorithm (Space Complexity). It includes program space and data space
2).Time required to complete the task of that algorithm (Time Complexity).

Space Complexity:
What is Space complexity?
When we design an algorithm to solve a problem, it needs some computer memory to complete its execution. For any algorithm,
memory is required for the following purposes...
 Memory required to store program instructions
 Memory required to store constant values
 Memory required to store variable values
 And for few other things
Space complexity of an algorithm can be defined as follows...
Total amount of computer memory required by an algorithm to complete its execution is called as space complexity of that
algorithm
Generally, when a program is under execution it uses the computer memory for THREE reasons. They are as follows...
Instruction Space: It is the amount of memory used to store compiled version of instructions.
Environmental Stack: It is the amount of memory used to store information of partially executed functions at the time of
function call.
Data Space: It is the amount of memory used to store all the variables and constants.
To calculate the space complexity, we must know the memory required to store different datatype values (according to
the compiler). For example, the C Programming Language compiler requires the following...
2 bytes to store Integer value,
4 bytes to store Floating Point value, 1 byte to

store Character value,

6 (OR) 8 bytes to store double value


Example 1
Consider the following piece of code... int square(int

a)

{
return a*a;
}
In above piece of code, it requires 2 bytes of memory to store variable 'a' and another 2 bytes of memory is used for return value.
That means, totally it requires 4 bytes of memory to complete its execution. And this 4 bytes of memory is fixed for any input
value of 'a'. This space complexity is said to be Constant Space Complexity.
Constant Space Complexity :If any algorithm requires a fixed amount of space for all input values then that space complexity is
said to be Constant Space Complexity

Example 2

Consider the following piece of code... int sum(int

A[], int n)
{
int sum = 0, i;
for(i = 0; i < n; i++) sum =
sum + A[i];
return sum;
}
In above piece of code it requires
'n*2' bytes of memory to store array variable 'a[]'

2 bytes of memory for integer parameter 'n'


4 bytes of memory for local integer variables 'sum' and 'i' (2 bytes each) 2 bytes of memory for

return value.

That means, totally it requires '2n+8' bytes of memory to complete its execution. Here, the amount of memory depends on the
input value of 'n'. This space complexity is said to be Linear Space Complexity.
Linear Space Complexity :If the amount of space required by an algorithm is increased with the increase of input value, then that
space complexity is said to be Linear Space Complexity

Time Complexity
What is Time complexity?
Every algorithm requires some amount of computer time to execute its instruction to perform the task. This computer time
required is called time complexity.
Time complexity of an algorithm can be defined as follows...
The time complexity of an algorithm is the total amount of time required by an algorithm to complete its execution.
Generally, running time of an algorithm depends upon the following...
 Whether it is running on Single processor machine or Multi processor machine.
 Whether it is a 32 bit machine or 64 bit machine
 Read and Write speed of the machine.
 The time it takes to perform Arithmetic operations, logical operations, return value and assignment operations etc.,
 Input data
Calculating Time Complexity of an algorithm based on the system configuration is a very difficult task because, the
configuration changes from one system to another system. To solve this problem, we must assume a model machine with specific
configuration. So that, we can able to calculate generalized time complexity according to that model machine.
To calculate time complexity of an algorithm, we need to define a model machine. Let us assume a machine with following
configuration...
1.Single processor machine
2.32 bit Operating System machine
3.It performs sequential execution
4.It requires 1 unit of time for Arithmetic and Logical operations
5.It requires 1 unit of time for Assignment and Return value
6.It requires 1 unit of time for Read and Write operations
Now, we calculate the time complexity of following example code by using the above defined model machine...

Example 1
Consider the following piece of code...
int sum(int a, int b)
{
return a+b;
}

In above sample code, it requires 1 unit of time to calculate a+b and 1 unit of time to return the value. That means, totally it takes
2 units of time to complete its execution. And it does not change based on the input values of a and b. That means for all input
values, it requires same amount of time i.e. 2 units.

Constant Time Complexity.:If any program requires fixed amount of time for all input values then its time complexity is said to
be Constant Time Complexity.
Example 2
Consider the following piece of code...
int sum(int A[], int n)
{
int sum = 0, i;
for(i = 0; i < n; i++) sum =
sum + A[i];
return sum;
}

For the above code, time complexity can be calculated as follows...


In above calculation
Cost is the amount of computer time required for a single operation in each line.
Repeatation is the amount of computer time required by each operation for all its repeatations. Total is the amount of computer

time required by each operation to execute.

So above code requires '4n+4' Units of computer time to complete the task. Here the exact time is not fixed. And it changes
based on the n value. If we increase the n value then the time required also increases linearly.
Totally it takes '4n+4' units of time to complete its execution and it is Linear Time Complexity.

Linear Time Complexity :If the amount of time required by an algorithm is increased with the increase of input value then that
time complexity is said to be Linear Time Complexity
Best Case,Worst Case and Average Case Efficiencies:
Best Case: It is the minimum number of steps that can be executed for a given problem is know as Best Case.
Worst Case: It is the maximum number of steps that can be executed for a given problem is know as Worst case.
Average Case: It is the Average number of steps that can be executed for a given problem is know as Average Case.

You might also like