0% found this document useful (0 votes)
17 views27 pages

CONTENTb Merged

Uploaded by

BRIJESH HANSA
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)
17 views27 pages

CONTENTb Merged

Uploaded by

BRIJESH HANSA
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/ 27

A REPORT

ON
DATA STRUCTURES AND ALGORITHMS
USING PYTHON
Summer Training Report submitted in partial fulfillment of
the requirement for the degree of
Bachelor of Technology
In
Electrical and Electronics Engineering

By

BRIJESH
(75115004920)
To

Department of Electrical and Electronics Engineering

Maharaja Surajmal Institute of Technology


Affiliated to Guru Gobind Singh Indraprastha University
New Delhi– 58

i
STUDENT CERTIFICATE

I, BRIJESH, Roll No. 75115004920, B.tech(Semester – 7th) of the Maharaja Surajmal Institute

of Technology, New Delhi hereby declare that the training report entitled “ DSA using python ”

is an original work and data provided in the study is authentic to the best of my knowledge. The

report has not been submitted to any other institute for the award of any other degree.

Brijesh
EEE
75115004920

Place - 767/ A,
last more, Gandhi nagar, Jammu,
Jammu and Kashmir 180004

ii
CERTIFICATE

iii
ACKNOWLEDGEMENT

It gives me a great sense of pleasure to present the report of the project work undertaken during

B. Tech. 7th semester. I owe special debt of gratitude to my Mentor Dr. Rakhi Kamra,

Department of Electrical and Electronics Engineering, for her constant support and guidance

throughout the course of my work. It is only her cognizant efforts that my endeavors have seen

light of the day. My deepest thanks to my Computer Programmer Mr. Sahil the Guide of the

project for guiding and correcting various documents of mine with attention and care. I also

take the opportunity to acknowledge the contribution of all faculty members of, Maharaja

Surajmal Institute of Technology, GGSIP University, New Delhi.

Student Assistant professor

Brijesh Dr. Rakhi Kamra

iv
ABSTRACT

This report delves into the world of Data Structures and Algorithms (DSA) within the context of

the Python programming language. DSA serves as the foundation of computer science, enabling

efficient problem-solving and data manipulation. Python, celebrated for its readability and

versatility, provides an ideal platform for the practical implementation and exploration of various

data structures and algorithms.

The report covers a range of critical topics, including the importance of data structures, their in-

depth analysis, and the intricate world of algorithms. It also touches on advanced data structures,

complexity analysis, and their applications in various domains. Furthermore, the report discusses

how mastering DSA in Python is fundamental for software development and other disciplines like

machine learning, game development, and cryptography.

v
vi
CONTENT

1. INTRODUCTION...…………………………………………………...1
2. IMPORTANCE OF DATA STRUCTURES…………………………..2
3. TYPES OF DATA STRUCTURES……………………………………3
3.1. LINEAR DATA STRUCTURES…………………………………3-6
3.1.1. ARRAY……………………………………………………..3
3.1.2. LINKED LISTS……………………………………………..3-4
3.1.3. QUEUE……………………………………………………...4-5
3.1.4. STACK……………………………………………………...5-6
3.2. NON LINEAR DATA STRUCTURES……………………….….6-13
3.2.1. GRAPH……………………………………………………..6-9
3.2.2. TREES……………………………………………………....9-13
3.3. ALGORITHMS…………………………………………………...13-15
3.3.1. SEARCHING……………………………………………13-14
3.3.2. SORTING……………………………………………….14-15
4. CODE……………………………………………………………….….16-18
5. CONCLUSION………………………………………………………...19
6. BIBLOGRAPHY.……………………………………………………...20

0
Chapter 1: INTRODUCTION

Data structures and algorithms (DSA) is a field of computer science that deals with the
organization and manipulation of data. It is also the study of how to design and implement
algorithms to solve problems in a computer.

Data structures are containers that organize and store data in a computer. Python provides a variety
of data structures, including lists, tuples, sets, dictionaries, and stacks.

Algorithms are step-by-step instructions for solving problems. Python provides a library of
algorithms for sorting, searching, and other common tasks.

DSA is essential for writing efficient and scalable code. By understanding DSA, you can write
code that is faster, uses less memory, and is easier to maintain.

Here are some examples of how DSA is used in the real world:

• Search engines: DSA is used to design search algorithms that can quickly and efficiently
find the information you are looking for on the web.
• Social media platforms: DSA is used to design algorithms that recommend friends, posts,
and other content to users.
• Online shopping platforms: DSA is used to design algorithms that recommend products to
customers and help them find the best deals.
• Video games: DSA is used to design algorithms that control the movement of characters
and objects in the game world.
• Financial trading systems: DSA is used to design algorithms that make automated trading
decisions.

DSA is a valuable skill for anyone who wants to work in software development, data science, or
other related fields. It is also a valuable skill for anyone who wants to learn how to write more
efficient and scalable code.

1
Chapter 2: IMPORTANCE OF DATA STRUCTURES

Data structures are essential for efficient storage, retrieval, and manipulation of data. They provide
a way to organize data in a way that is easy to access and use. Data structures are used in a wide
variety of applications, including operating systems, databases, compilers, and web browsers.

Here are some of the key reasons why data structures are important:

• Efficiency: Data structures can help to improve the efficiency of your code by reducing
the time and space complexity of algorithms. For example, a hash table can be used to
search for an element in a dataset in O(1) time, while a linear search would require O(n)
time.
• Scalability: Data structures can help to make your code more scalable by allowing it to
handle larger amounts of data efficiently. For example, a linked list can be used to store a
dynamic list of elements, while an array would have to be resized whenever a new element
is added.
• Reusability: Data structures are often reusable, which can save you time and effort when
writing code. For example, a stack data structure can be used to implement a function call
stack, a back button in a web browser, or an undo/redo mechanism in a text editor.
• Abstraction: Data structures provide a way to abstract the underlying complexity of a
problem and simplify it, making it easier to understand and solve. For example, a queue
data structure can be used to model a line of people waiting for service, without having to
worry about the specific details of how the line is implemented.

In addition to these general benefits, data structures are also essential for many specific
applications. For example, databases use data structures to store and retrieve data efficiently,
operating systems use data structures to manage memory and processes, and compilers use data
structures to parse and generate code.

Overall, data structures are a fundamental component of computer science and software
development. By understanding and using data structures effectively, you can write more efficient,
scalable, and reusable code.

Here are some examples of how data structures are used in industry:

• Web development: Data structures are used in web development to store and retrieve data
from databases, to implement caching mechanisms, and to improve the performance of
web applications.
• Mobile development: Data structures are used in mobile development to store and retrieve
data on devices, to implement user interfaces, and to optimize the performance of mobile
applications.
• Big data: Data structures are used in big data applications to store and process large
amounts of data efficiently.
• Machine learning: Data structures are used in machine learning algorithms to store and
process data, to train models, and to make predictions.
2
Chapter 3: TYPES OF DATA STRUCTURES

3.1. LINEAR DATA STRUCTURES


3.1.1 . ARRAY

An array is a linear data structure that stores a collection of elements of the same type in
contiguous memory locations. This means that the elements of an array are stored one after the
other in memory.

Arrays are often used to store and manipulate data that needs to be processed in a sequential order,
such as a list of items in a shopping cart or a queue of customers waiting to be served.

Arrays have a fixed size, meaning that the number of elements that can be stored in an array cannot
be changed once the array is created.

To access an element in an array, you must know the index of the element. The index of an element
is its position in the array, starting from 0.

3.1.2. LINKED LISTS

A linked list is a linear data structure that stores a collection of elements of any type. The elements
in a linked list are not stored in contiguous memory locations. Instead, each element in the linked
list contains a reference to the next element in the list.

The first element in a linked list is called the head of the list. The last element in a linked list is
called the tail of the list.

To access an element in a linked list, you must start at the head of the list and follow the references
to the next elements until you reach the desired element.

3
3.1.3. QUEUE
A queue is a linear data structure that follows a First-In-First-Out (FIFO) order. This means that
the first element added to the queue is the first element removed from the queue.

Queues are often used to implement waiting lines, such as the line of customers waiting to be
served at a checkout counter or the line of jobs waiting to be processed on a computer.

Queues are also used to implement buffers, which are temporary storage areas for data that is
being transferred between two processes. For example, a buffer can be used to store the data that
is being sent over a network connection.

Queues can be implemented in a variety of ways, but the most common implementation is to use
a linked list. A linked list is a dynamic data structure, meaning that its size can be changed at any
time. This makes linked lists well-suited for implementing queues, since queues also need to be
able to change their size as elements are added and removed.

queue = []

def addque(x):
queue.append(x)

def delque():
queue.pop(0)

4
def printque():
print(queue)

subsubmainloop = 1
while(subsubmainloop!=0):
mainloopchoice = '0'
submainloopchoice = '0'
subsubmainloop = int(input('Enter a Choice:\n\n0 to exit:\n1 to add element
to Queue\n2 to Delete element from the queue\n3 to print the Queue\n4 to go to
back menu\t'))

if(subsubmainloop==0):
print('Thank you for using my software\n\ncopyright 2023 - Brijesh')
elif(subsubmainloop==1):
x = input('Enter value to add to queue:\t')
addque(x)
elif(subsubmainloop==2):
delque()
elif(subsubmainloop==3):
printque()
elif(subsubmainloop==4):
subsubmainloop=='0'
print("thank you for using queue")
break
else:
print('Error: invalid input, please try again or enter 0 to exit')

3.1.4. STACK
Stacks and queues are both linear data structures, but they have different orders of operation. A
stack is a LIFO (Last In First Out) data structure, while a queue is a FIFO (First In First Out) data
structure.

This means that the last element added to a stack is the first element removed, and the first element
added to a queue is the first element removed.

Stacks and queues can be implemented in a variety of ways, but the most common
implementations use arrays or linked lists.

Array implementation

An array implementation of a stack or queue is simple and efficient, but it has a disadvantage of
having a fixed size. If the stack or queue needs to grow beyond its fixed size, the array needs to
be resized, which can be expensive.

Linked list implementation


5
A linked list implementation of a stack or queue is more dynamic, meaning that the stack or queue
can grow or shrink as needed. However, linked list implementations are typically less efficient
than array implementations.

3.2. NON LINEAR DATA STRUCTURES

3.2.1. GRAPH
A graph is a data structure that consists of a set of nodes (also called vertices) and a set of edges
(also called arcs) that connect the nodes. The nodes can represent any type of entity, such as
people, places, or things. The edges can represent any type of relationship between the nodes, such
as friendship, proximity, or ownership.

Graphs are a powerful tool for representing complex relationships between objects. They can be
used to model a wide variety of real-world problems, such as social networks, transportation
networks, and communication networks.

Graphs can be represented in a variety of ways, but the most common representation is to use an
adjacency matrix. An adjacency matrix is a square matrix where each entry in the matrix
represents the weight of the edge between the corresponding nodes in the graph. If there is no
edge between the nodes, the weight of the edge is typically set to infinity.

Another common way to represent graphs is to use an adjacency list. An adjacency list is a linked
list of edges for each node in the graph. Each edge in the linked list contains a reference to the
other node that the edge connects to.

Here is an example of a simple graph:

A-B
| /
|/
C

This graph has three nodes: A, B, and C. There are two edges in the graph: an edge from A to B
and an edge from B to C.

Graphs can be used to solve a variety of problems, including:

6
• Finding the shortest path between two nodes in a graph.
• Finding the minimum spanning tree of a graph.
• Finding the maximum clique in a graph.
• Finding the connected components of a graph

# class to create graph object and for creating methods to implement important
graph elements like Vertex or Edge
class Graph:
def __init__(self):
# dictionary containing keys that map to the corresponding vertex object
self.vertices = {}

def add_vertex(self, key):


"""Add a vertex with the given key to the graph."""
vertex = Vertex(key)
self.vertices[key] = vertex

def get_vertex(self, key):


"""Return vertex object with the corresponding key."""
return self.vertices[key]

def __contains__(self, key):


return key in self.vertices

def add_edge(self, src_key, dest_key, weight=1):


"""Add edge from src_key to dest_key with given weight."""
self.vertices[src_key].add_neighbour(self.vertices[dest_key], weight)

def does_edge_exist(self, src_key, dest_key):


"""Return True if there is an edge from src_key to dest_key."""
return self.vertices[src_key].does_it_point_to(self.vertices[dest_key])

def __iter__(self):
return iter(self.vertices.values())

7
# vertex class to handle vertex related logic such as placement and
verification, etc
class Vertex:
def __init__(self, key):
self.key = key
self.points_to = {}

def get_key(self):
"""Return key corresponding to this vertex object."""
return self.key

def add_neighbour(self, dest, weight):


"""Make this vertex point to dest with given edge weight."""
self.points_to[dest] = weight

def get_neighbours(self):
"""Return all vertices pointed to by this vertex."""
return self.points_to.keys()

def get_weight(self, dest):


"""Get weight of edge from this vertex to dest."""
return self.points_to[dest]

def does_it_point_to(self, dest):


"""Return True if this vertex points to dest."""
return dest in self.points_to

g = Graph()

subsubmainloop = 1
while(subsubmainloop!=0):
subsubmainloop = int(input('\nEnter a choice:\n0 to quit program\n1 to add
Vertex\n2 to add Edge\n3 to display graph:\n4 to go to back menu\n-->\t'))

# choice to exit program


if(subsubmainloop==0):
mainloopchoice = '0'
submainloopchoice = '0'
print('\n\n***Thank you for using my software***\n***copyright 2023 -
Brijesh***')
# choice to add vertex / node to the graph
elif(subsubmainloop==1):
key = input('Enter key value:\t')
if key not in g:
g.add_vertex(key)
else:
print('Vertex already exists.')
# choice to connect two vertex with a edge

8
elif(subsubmainloop==2):
src = input('Enter source value:\t')
dest = input('Enter destination value:\t')
wt = input('Enter weight value:\t')

if src not in g:
print('Vertex {} does not exist.'.format(src))
elif dest not in g:
print('Vertex {} does not exist.'.format(dest))
else:
if not g.does_edge_exist(src, dest):
if(wt.isnumeric()):
g.add_edge(src, dest, wt)
else:
g.add_edge(src, dest)
else:
print('Edge already exists.')
# print current graph
elif(subsubmainloop==3):
print('Vertices: ', end='')
for v in g:
print(v.get_key(), end=' ')
print()

print('Edges: ')
for v in g:
for dest in v.get_neighbours():
w = v.get_weight(dest)
print('(src={}, dest={}, weight={}) '.format(v.get_key(),
dest.get_key(), w))
print()
# to go to back menu
elif(subsubmainloop==4):
subsubmainloop='0'
print("***Thank you for using graph in dsa @ BRIDSA***")
break

else:
print('\n\n***Error: invalid choice***')

3.2.2. TREES
It is a non-linear data structure that consists of various linked nodes. It has a hierarchical tree
structure that forms a parent-child relationship.

9
#define node class
class BSTNode:
def __init__(self, val=None):
self.left = None
self.right = None
self.val = val

# insert method in node class


def insert(self, val):
if not self.val:
self.val = val
return

if self.val == val:
return

if val < self.val:


if self.left:
self.left.insert(val)
return
self.left = BSTNode(val)
return

if self.right:
self.right.insert(val)
return
self.right = BSTNode(val)

# get min of all keys using get_min() method


def get_min(self):
current = self
while current.left is not None:
current = current.left
print('Minimum Value:',current.val)

# get max of all keys using get_min() method


10
def get_max(self):
current = self
while current.right is not None:
current = current.right
print('Maximum Value:',current.val)

# delete method to remove any node by key


def delete(self, val):
if self == None:
return self
if self.right == None:
return self.left
if self.left == None:
return self.right
if val < self.val:
if self.left:
self.left = self.left.delete(val)
return self
if val > self.val:
if self.right:
self.right = self.right.delete(val)
return self
min_larger_node = self.right
while min_larger_node.left:
min_larger_node = min_larger_node.left
self.val = min_larger_node.val
self.right = self.right.delete(min_larger_node.val)
return self

# checl if node exist with key


def exists(self, val):
if val == self.val:
return True

if val < self.val:


if self.left == None:
return False
return self.left.exists(val)

if self.right == None:
return False
return self.right.exists(val)

# method to print the tree in preoder


def preorder(self, vals):
if self.val is not None:
vals.append(self.val)
if self.left is not None:
self.left.preorder(vals)

11
if self.right is not None:
self.right.preorder(vals)
return vals

# method to print the tree inorder


def inorder(self, vals):
if self.left is not None:
self.left.inorder(vals)
if self.val is not None:
vals.append(self.val)
if self.right is not None:
self.right.inorder(vals)
return vals

# method to print three in post order


def postorder(self, vals):
if self.left is not None:
self.left.postorder(vals)
if self.right is not None:
self.right.postorder(vals)
if self.val is not None:
vals.append(self.val)
return vals

bst = BSTNode()
subsubmainloop = 1
while(subsubmainloop!=0):
subsubmainloop = int(input('\n\nEnter a choice:\n1 to insert node\n2 to get
minimum key value\n3 to get maximum keyvalue\n4 to delete a node with key
value\n5 to check if a element exists\n6 to get tree in preorder\n7 to get tree
as inorder\n8 to get tree in postorder\n9 to go to back menu\n0 to exit
program'))
if(subsubmainloop==0):
mainloopchoice = '0'
submainloopchoice = '0'
print('\n\nThank you for using my software\nCopyright 2023 - brijesh')
elif(subsubmainloop==1):
val = int(input('\n-> Enter a number to insert in tree:\t'))
bst.insert(val)
elif(subsubmainloop==2):
bst.get_min()
elif(subsubmainloop==3):
bst.get_max()
elif(subsubmainloop==4):
val = int(input('\n-> Enter a key to delete node in the tree:\t'))
bst.delete(val)
elif(subsubmainloop==5):

12
val = int(input('\n-> Enter a key to check if it exists in the
tree:\t'))
check = bst.exists(val)
print(check)
elif(subsubmainloop==6):
print(bst.preorder([]))
elif(subsubmainloop==7):
print(bst.inorder([]))
elif(subsubmainloop==8):
print(bst.postorder([]))
elif(subsubmainloop==9):
subsubmainloop = '0'
print("thank you for using tree in dsa")
break
else:
print('\n\nError: Invalid choice,\nplease try again and enter a valid
choice\nor enter 0 to exit program.')

3.3. ALGORITHMS

3.3.1. SEARCHING
Searching algorithms, also known as search algorithms, are a fundamental component of computer
science and data structures. They are used to find the presence or location of a specific element
within a collection of data, such as an array, list, or database. Searching algorithms are crucial for
tasks like finding a particular item in a list, searching for a specific record in a database, or locating
a particular value in a data structure.

a. LINEAR SEARCHING

Linear searching is a simple search algorithm that works by sequentially checking each element
in a list until the desired element is found. If the element is not found, the algorithm returns an
indication that the element is not in the list.

Linear searching is easy to implement and understand, but it can be inefficient for large lists.
The worst-case time complexity of linear searching is O(n), where n is the number of elements
in the list. This means that the search time will increase linearly with the size of the list.

13
b. BINARY SEARCH

Binary search is a search algorithm that works by repeatedly dividing a sorted list in half and
comparing the target value to the middle element of the list. If the target value is equal to the
middle element, the search is complete. If the target value is less than the middle element, the
search continues in the lower half of the list. If the target value is greater than the middle element,
the search continues in the upper half of the list. This process is repeated until the target value is
found or the list is exhausted.

Binary search is a very efficient search algorithm, especially for large sorted lists. The worst-case
time complexity of binary search is O(log n), where n is the number of elements in the list. This
means that the search time will increase logarithmically with the size of the list.

3.3.2. SORTING

a. BUBBLE SORT
Bubble sort is a simple sorting algorithm that repeatedly steps through the list, compares adjacent
elements, and swaps them if they are in the wrong order. The pass through the list is repeated until
the list is sorted. Bubble sort has a time complexity of O(n^2) in the worst case.

14
b. MERGE SORT
Merge sort is a divide-and-conquer algorithm that divides the list into smaller sublists, sorts them,
and then merges the sorted sublists to produce a sorted list. Merge sort has a time complexity of
O(n log n) in the worst case, making it more efficient for large datasets.

c. INSERTION SORT
Insertion sort builds the sorted list one element at a time. It takes an element from the unsorted
portion and inserts it into its correct position in the sorted portion. It has a time complexity of
O(n^2) but can be efficient for small datasets.

d. SELECTION SORT
Selection sort divides the list into two parts: a sorted and an unsorted portion. It repeatedly selects
the smallest (or largest) element from the unsorted portion and moves it to the sorted portion.
Selection sort also has a time complexity of O(n^2).

15
Chapter 4: CODE
"""Sort_SpreadData.ipynb

Automatically generated by Colaboratory.

Original file is located at


https://colab.research.google.com/drive/1ofTLArrQU-UVj1gTKsOhx8P0or9DEH7Y
"""

# Program to implement bubble sort on data taken from external source


# in our case a spreadsheet, catching marks column from sheet1 and
# saving sorted data back to the sheet at SortedData page, if page
# already exist, save to SortedData with a number in a new sheet

# pip install pandas


import pandas as pd

# Function to categorize marks into different ranges


def categorize_marks(marks):
if marks <= 25:
return "0-25"
elif marks <= 50:
return "26-50"
elif marks <= 75:
return "51-75"
else:
return "76-100"

# Function to perform bubble sort


def bubble_sort(data):
n = len(data)
for i in range(n):
swapped = False
for j in range(0, n-i-1):
if data[j]["marks"] > data[j+1]["marks"]:
data[j], data[j+1] = data[j+1], data[j]
swapped = True
# If no two elements were swapped in the inner loop, the data is already
sorted
if not swapped:
break
return data

# Read data from the Excel file


file_path = "data.xlsx" # Replace with the path to your Excel file
original_sheet_name = "Sheet1" # Replace with the name of the original sheet

16
# Read data from the original sheet
data = pd.read_excel(file_path,
sheet_name=original_sheet_name).to_dict(orient="records")

# Sort data based on marks using bubble sort algorithm


sorted_data = bubble_sort(data.copy()) # Create a copy of data to preserve the
original data

# Categorize marks and add a new column 'category'


for student in sorted_data:
student["category"] = categorize_marks(student["marks"])

# Create a new Excel writer object


with pd.ExcelWriter(file_path, engine='openpyxl', mode='a') as writer:
# Generate a unique new sheet name
sheet_name = "SortedData"
i = 1
while sheet_name in writer.book.sheetnames:
sheet_name = f"SortedData_{i}"
i += 1

# Write the sorted data to a new sheet


sorted_df = pd.DataFrame(sorted_data)
sorted_df.to_excel(writer, index=False, sheet_name=sheet_name)

print(f"Sorted data has been saved to the '{sheet_name}' sheet in the same Excel
file.")
OUTPUT

17
Sorted data of 5th semester EEE students.

18
Chapter 5: CONCLUSION

Data structures and algorithms (DSA) are the foundation of computer science. DSA is the study
of how to organize and store data in a computer so that it can be accessed and manipulated
efficiently. It is also the study of how to design and implement algorithms to solve problems in a
computer.

Python is a general-purpose programming language that is well-suited for DSA. It is a relatively


easy language to learn, and it has a rich library of data structures and algorithms.

In this report, we have discussed the basic data structures and algorithms that are implemented in
Python. We have also seen how to use these data structures and algorithms to solve real-world
problems.

Here is a summary of the key takeaways from this report:

• Data structures are containers that organize and store data in a computer. Python provides
a variety of data structures, including lists, tuples, sets, dictionaries, and stacks.
• Algorithms are step-by-step instructions for solving problems. Python provides a library
of algorithms for sorting, searching, and other common tasks.
• DSA is essential for writing efficient and scalable code. By understanding DSA, you can
write code that is faster, uses less memory, and is easier to maintain.

19
Chapter 6: BIBLOGRAPHY

I. Data taken from IPU Ranklist ,B tech , EEE , 5th semester.

https://www.ipuranklist.com/ranklist/btech?batch=20&sem=5&college=MSIT&sh

ift=M&branch=EEE

II. Necaise RD." Data structures and algorithms using Python”. 2011.

III. Lafore R, Broder A, Canning J. “Data Structures & Algorithms in Python”.

Addison-Wesley Professional; 2022 Sep 6.

IV. Lee KD, Lee KD, Steve Hubbard SH. “Data Structures and Algorithms with

Python”. Springer; 2015.

V. Karumanchi N. “Data Structures and Algorithmic Thinking with Python”.

CareerMonk Publications; 2016.

VI. Stephens R. Essential algorithms,” a practical approach to computer algorithms

using Python and C”. John Wiley & Sons; 2019 May 29.

VII. McKinney W. “Data structures for statistical computing in python”. InProceedings

of the 9th Python in Science Conference 2010 Jun 28 (Vol. 445, No. 1, pp. 51-56).

VIII. Delgado-Friedrichs O. “Data structures and algorithms for tilings” I. Theoretical

Computer Science. 2003 Jul 15;303(2-3):431-45.

20

You might also like