Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 11

SYED MUHAMMAD BIN QASIM 02-131222-011

BAHRIA UNIVERSITY, (Karachi Campus)


Department of Software Engineering
Assignment 2 – Fall 2023
Based on: CLO-2

COURSE TITLE: DATA STRUCTURES & ALGORITHMS


COURSE CODE: CSC - 221 Class: BSE- 3(C)
Course Instructor: ENGR. MAJID KALEEM
Submission Date: 23.11.2023
Submitted by: SYED MUHAMMAD BIN QASIM EN: 02-131222-011

TASK 1: Algorithmic Efficiency and Optimization

Quick Sort:

Quick Sort is a divide-and-conquer sorting algorithm that is considered to be one of the


most efficient sorting algorithms in practice. It works by recursively dividing the input list
into smaller sub lists until each sub list is sorted, and then merging the sorted sub lists
together.

 Illustration of Quicksort:
SYED MUHAMMAD BIN QASIM 02-131222-011

 Time Complexity:

 Best Case: Ω (N log (N))


The best-case scenario for quicksort occur when the pivot chosen at the each
step divides the array into roughly equal halves.
In this case, the algorithm will make balanced partitions, leading to efficient
Sorting.

 Average Case: θ ( N log (N))


Quicksort’s average-case performance is usually very good in practice, making it
one of the fastest sorting Algorithm.

 Worst Case: O(N2)


The worst-case Scenario for Quicksort occur when the pivot at each step
consistently results in highly unbalanced partitions. When the array is already
sorted and the pivot is always chosen as the smallest or largest element. To
mitigate the worst-case Scenario, various techniques are used such as choosing
a good pivot (e.g., median of three) and using Randomized algorithm
(Randomized Quicksort ) to shuffle the element before sorting.

 Auxiliary Space: O(1), if we don’t consider the recursive stack space. If we


consider the recursive stack space then, in the worst case quicksort could
make O(N).

geeksforgeeks

 Space complexity:
SYED MUHAMMAD BIN QASIM 02-131222-011

The space complexity of QuickSort is O(log n), which means that the amount of memory
required to sort a list grows logarithmically with the size of the list. This is because
QuickSort uses a stack to keep track of the sublists that need to be sorted.

 Code implementation of the Quick Sort:


C++ language:

#include <bits/stdc++.h>

using namespace std;

int partition(int arr[],int low,int high)

//choose the pivot

int pivot=arr[high];

//Index of smaller element and Indicate

//the right position of pivot found so far

int i=(low-1);

for(int j=low;j<=high;j++)

//If current element is smaller than the pivot

if(arr[j]<pivot)

//Increment index of smaller element

i++;

swap(arr[i],arr[j]);

}
SYED MUHAMMAD BIN QASIM 02-131222-011

swap(arr[i+1],arr[high]);

return (i+1);

// The Quicksort function Implement

void quickSort(int arr[],int low,int high)

// when low is less than high

if(low<high)

// pi is the partition return index of pivot

int pi=partition(arr,low,high);

//Recursion Call

//smaller element than pivot goes left and

//higher element goes right

quickSort(arr,low,pi-1);

quickSort(arr,pi+1,high);

int main() {

int arr[]={10,7,8,9,1,5};
SYED MUHAMMAD BIN QASIM 02-131222-011

int n=sizeof(arr)/sizeof(arr[0]);

// Function call

quickSort(arr,0,n-1);

//Print the sorted array

cout<<"Sorted Array\n";

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

cout<<arr[i]<<" ";

return 0;

 To Enhance The Algorithm Proficiency:


The basic quicksort algorithm should be improved in three ways:

 When the array segment is small (say size 10 or less) recursive calls are
relatively expensive, so use a different algorithm.

 A better choice of pivot value, the median of three, will improve execution time.

 In the worst case, quicksort uses space linear in the array size; this can be
modified to be logarithmic.

1. Insertion sort is faster than quicksort on small arrays.

It turn out that insertionsort is faster than quicksort on small arrays. This is because
quicksort makes several recursive calls, and method calls do take time. After all, a
frame for the call has to be placed on the call stack, arguments values have to be
assigned to parameters, and so forth. Just what do we mean by “small”? That may
depend on the computer on which the method is being executed. In the 1970’s and
1980’s, people did experiments to figure out what “small” meant in this case. Today,
SYED MUHAMMAD BIN QASIM 02-131222-011

let’s just say for the sake of convenience that arrays of size at most 10 are sorted faster
using insertionsort. So, in the method given below, arrays of size at most 10 will be
sorted using insertionsort.

2. Use the median of three for the pivot value.

Quicksort is slowest when the pivot is always the smallest or largest possible value.
The best possible pivot is the median of the segment b[h..k] being sorted. That median
can actually be calculated and used, but the calculation is too slow. Instead, one
generally uses the median of three values: b[h], b[(h+k)/2], and b[k]. To the right, we
define a method to swap the median of three values of b[h..k] into b[h]. We leave its
implementation to you. In the improved quicksort algorithm, we’ll call this method before
calling method partition.

3. Use at most logarithmic space

When the pivot is always the smallest value of the segment to be partitioned, the depth
of recursion is linear in the size of the array, so the space required is linear in the size of
the array. The first step in changing this is to sort the smaller of the two partitions
created by the partition algorithm first, as shown in the algorithmcs. This means that the
largest partition is sorted last and that nothing else is done in the method after the
largest partition is sorted. If you know about tail-calls, you know these are called tail-
calls, and if tail-calls are optimized by the compiler, no frames for them are created. If
you don’t know about tail recursion and tail calls, don’t be concerned; we’ll show how to
implement this efficiently below.

cs.cornell.edu

 Bottlenecks of Quick Sort:

 It has a worst-case time complexity of O(N2), which occurs when the pivot is
chosen poorly.
SYED MUHAMMAD BIN QASIM 02-131222-011

 It is not a good choice for small data sets.

 It is not a stable sort, meaning that if two elements have the same key, their
relative order will not be preserved in the sorted output in case of quick sort,
because here we are swapping elements according to the pivot’s position
(without considering their original positions).

 Trade-Off of Quick Sort:

Quicksort has many advantages, such as being fast, easy to implement, and in-place,
which means that it does not require extra space. Quicksort also has some
disadvantages, such as being unstable, sensitive to the choice of the pivot, and
vulnerable to the worst case. Quicksort can also cause stack overflow if the recursion
depth is too high.

 Comparision between optimized version with the standard


implementation:

One way to optimize quicksort for different types of data is to choose a suitable pivot
element. A good pivot element is one that divides the array into two roughly equal
subarrays, which minimizes the number of recursive calls and reduces the risk of hitting
the worst case. There are several methods to choose a pivot element, such as picking
the first, the last, the middle, or a random element, or using a median-of-three or a
median-of-medians strategy. Another way to optimize quicksort for different types of
data is to use a hybrid approach, which combines quicksort with another sorting
algorithm, such as insertion sort or heap sort, for small subarrays or nearly sorted
arrays. This can improve the performance by reducing the overhead of recursion and
taking advantage of the existing order. linkedin
SYED MUHAMMAD BIN QASIM 02-131222-011

TASK 2: Graph Algorithms in Real-world Applications

 Graph Model:

In this problem, we can represent the road network as a graph, where intersections are
represented as nodes and roads are represented as edges. The weight of each edge
represents the distance or travel time between two intersections.

 Choice of Algorithm:

Dijkstra's algorithm is a suitable choice for this problem because it efficiently finds the
shortest path between two nodes in a graph with non-negative edge weights. In the
context of route planning, Dijkstra's algorithm can find the shortest route between a
starting point and a destination point in the road network.
SYED MUHAMMAD BIN QASIM 02-131222-011

 Implementation:

The implementation of Dijkstra's algorithm involves maintaining a priority queue of


nodes, where each node is associated with a tentative distance from the starting point.
Initially, the tentative distance for all nodes is set to infinity except for the starting point,
which is set to zero. The algorithm then iteratively extracts the node with the smallest
tentative distance from the priority queue and explores its unvisited neighbors. For each
unvisited neighbor, the tentative distance is updated if the total distance through the
current node is shorter than the current tentative distance. The process continues until
the destination node is reached or until all nodes have been visited.

 Effectiveness:

Dijkstra's algorithm is an efficient algorithm for finding shortest paths in graphs with non-
negative edge weights. In the context of route planning, it can effectively find the
shortest route between a starting point and a destination point in a road network, even if
the route involves multiple roads and turns.
SYED MUHAMMAD BIN QASIM 02-131222-011

 Modifications:

To better suit the real-world context of route planning, some modifications can be made
to the algorithm. For instance, the algorithm can be extended to handle traffic
information by incorporating edge weights that reflect real-time traffic conditions.
Additionally, the algorithm can be modified to consider factors such as road type
(highways, secondary roads, etc.), toll roads, and traffic restrictions.

 Challenges and Limitations:

One challenge with using Dijkstra's algorithm for route planning is that it assumes real-
time traffic information is available. In reality, traffic conditions may not always be
accurately known, and the algorithm may not always provide the most optimal route.
Additionally, the algorithm may not be suitable for finding routes that require specific
constraints, such as avoiding certain roads or areas. geeksforgeeks

study.com

Conclusion:

Dijkstra's algorithm is a powerful tool for solving route planning problems in road
networks. While it has some limitations, it can be effectively adapted to real-world
scenarios by incorporating traffic information and considering additional factors.

REFERENCES:
The contents of both tasks are taken by websites:
 geeksforgeeks

 study.com
 linkedin
SYED MUHAMMAD BIN QASIM 02-131222-011

 cs.cornell.edu

You might also like