0% found this document useful (0 votes)
3 views37 pages

Project_documentation in space n

The document outlines the implementation of a Data Structure Visualizer using Tkinter, aimed at making data structure concepts more accessible through an interactive graphical user interface. It details various data structures such as arrays, linked lists, binary trees, and graphs, along with their functionalities and sorting algorithms. The program allows users to visualize operations like adding, deleting elements, and sorting through animations, enhancing understanding of these concepts.

Uploaded by

lihit19426
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)
3 views37 pages

Project_documentation in space n

The document outlines the implementation of a Data Structure Visualizer using Tkinter, aimed at making data structure concepts more accessible through an interactive graphical user interface. It details various data structures such as arrays, linked lists, binary trees, and graphs, along with their functionalities and sorting algorithms. The program allows users to visualize operations like adding, deleting elements, and sorting through animations, enhancing understanding of these concepts.

Uploaded by

lihit19426
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/ 37

“Foundations of Programming

(Cohort-1)”

”Implementation of the data structure


visualizer using Tkinter”

Professor: Dr.Nelda Kote

Name: Florian Hiso

1
Contents
1 Introduction 4

2 Implementation of data structures 4


2.1 Array class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Linked Lists class . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Binary Tree class . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Graph class . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5 Sorting algorithms . . . . . . . . . . . . . . . . . . . . . . . . 5
2.6 Data structure implementation code . . . . . . . . . . . . . . . 6

3 DataStructureVisualizer 11
3.1 User interface (UI) . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2 Visualization . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3 Button functions . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 Data structure visualizer code . . . . . . . . . . . . . . . . . . 12

4 A general look into the program 33

2
List of Figures
1 The starting look of the application . . . . . . . . . . . . . . . 33
2 The adding of elements . . . . . . . . . . . . . . . . . . . . . . 34
3 The deleting of elements . . . . . . . . . . . . . . . . . . . . . 34
4 Randomizing an array . . . . . . . . . . . . . . . . . . . . . . 34
5 Random array . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
6 Bubble sort visualized . . . . . . . . . . . . . . . . . . . . . . 35
7 Linked List . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
8 Binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
9 Inorder traversal . . . . . . . . . . . . . . . . . . . . . . . . . 36
10 Inorder traversal saved in the file . . . . . . . . . . . . . . . . 36
11 Graphs visualized . . . . . . . . . . . . . . . . . . . . . . . . 37
12 DFS visualized . . . . . . . . . . . . . . . . . . . . . . . . . . 37
13 DFS traversal saved in the file . . . . . . . . . . . . . . . . . 37

3
1 Introduction
The Data Structure Visualizer aims to be an interactive tool designed to make
data structure concepts more digestible for students and professionals. By
providing a rich graphical user interface, the program makes complex data
structures such as arrays, binary trees, graphs, and different sorting algo-
rithms more intuitive. Users can select different data structures and perform
several operations like adding or deleting certain elements, inserting random
data, and visualizing some popular sorting algorithms such as Bubble Sort,
Selection Sort, and Insertion Sort. Furthermore, the program also includes
things like graph traversal methods and tree traversal methods. Each anima-
tion is done step by step, helping the user to understand the process clearly.
Another feature of this application is also the adjustable speed animation,
which gives the user a more in-depth look of every single step.

2 Implementation of data structures


The implementation of data structures is done in a separate file called
data structures.py. The file serves as the backbone of the application and
holds the logic behind every implementation. Each structure in the program
is done in a separate class, using different methods for sorting and traversing.

2.1 Array class


The Array class represents a simple array structure. It supports things like
adding the elements, deleting the elements, and randomization. The random-
ization operation will populate the array with random values with the goal
to test different sorting algorithms, hence this class will act as the foundation
for the array sorting functionality.

2.2 Linked Lists class


Another data structure implementation is the linked list. The linked list has
similar functionalities to the array, such as insertion, deletion, and traversing
though the array. The visualization part will also be responsible to display
the node and the pointer which points to the next node.

4
2.3 Binary Tree class
The binary tree class will provide all the necessary method to implement a
binary search tree, as well as the tree traversals. Firstly, each element in the
tree will enter following a level order manner. This way it insures that the
binary tree remains balanced. Furthermore, methods such as randomization
and deletion are also part of the class Binary Tree. Lastly, the class will also
include the three main types of traversal in a tree.

• Inorder Traversal: Visits nodes in the order left → root → right.

• Preorder Traversal: Visits nodes in the order root → left → right.

• Postorder Traversal: Visits nodes in the order left → right → root.

2.4 Graph class


A graph is another non-linear data structure that is implemented in our
program. Each node in the graph is separated by classifying it as source
node or destination node. We use a queue in order to properly insert and
delete nodes from the graph. Other methods that are included in the graph
class are methods for traversing the graph. The methods are listed as follows

• DFS (Depth-First Search): Explores as far as possible along a branch


before backtracking.

• BFS (Breadth-First Search): Visits nodes level by level. This class is


crucial for understanding graph theory and traversal techniques.

2.5 Sorting algorithms


The sorting algorithm provide a clear explanation on how sorting is done to
an array. Each sorting algorithm is animated step by step and the operations
of each step are labeled. The sorting algorithms that have been implemented
are:

• Bubble Sort: Repeatedly swaps adjacent elements to sort the array.

• Selection Sort: Finds the smallest element in the unsorted section and
swaps it with the first unsorted element

5
• Insertion Sort: Builds a sorted section by inserting elements into their
correct position. Each algorithm returns intermediate steps to enable
step-by-step visualization

2.6 Data structure implementation code


The code that implements all the aforementioned classes is displayed below:

# D e f i n i n g a c l a s s Node which w i l l be used t o c r e a t e t h e


node f o r t h e t r e e s
c l a s s Node :
def i n i t ( s e l f , value ) :
s e l f . value = value
s e l f . l e f t = None
s e l f . r i g h t = None
#BinarySearch t r e e w i l l be used t o c r e a t e a b i n a r y t r e e
which w i l l perform t h i n g s l i k e i n s e r t i o n , d e l e t i o n ,
traversing etc .
c l a s s BinaryTree :
def init ( self ) :
s e l f . r o o t = None

def i n s e r t ( s e l f , v a l u e ) :
i f not s e l f . r o o t :
s e l f . r o o t = Node ( v a l u e )
return

queue = [ s e l f . r o o t ] #Using a queue t o k e e p t h e


t r a c k o f t h e nodes ( f o r l e v e l o r d e r t r a v e r s a l )
while queue : #l e v e l o r d e r t r a v e r s a l ( t h a t s how t h e
we w i l l i n s e r t t h e nodes i n t h e t r e e ) ( making
sure i t s balanced )
node = queue . pop ( 0 )
i f not node . l e f t :
node . l e f t = Node ( v a l u e )
break
e l i f not node . r i g h t :
node . r i g h t = Node ( v a l u e )
break

6
queue . append ( node . l e f t )
queue . append ( node . r i g h t )

def g e t t r a v e r s a l s t e p s ( s e l f , t r a v e r s a l t y p e ) : #t h e
t r a v e r s a l t y e s of t r e e s are inorder , preorder ,
postorder

steps = [ ]

def i n o r d e r ( node ) : #i n o r d e r t r a v e r s a l l e f t , root ,


right
i f node :

i n o r d e r ( node . l e f t )

s t e p s . append ( node )

i n o r d e r ( node . r i g h t )

def p r e o r d e r ( node ) : #p r e o r d e r t r a v e r s a l r o o t , l e f t ,
right
i f node :

s t e p s . append ( node )

p r e o r d e r ( node . l e f t )

p r e o r d e r ( node . r i g h t )

def p o s t o r d e r ( node ) : #p o s t o r d e r t r a v e r s a l l e f t ,
right , root
i f node :

p o s t o r d e r ( node . l e f t )

p o s t o r d e r ( node . r i g h t )

s t e p s . append ( node )

traversal functions = {

7
” inorder ” : inorder ,
” preorder ” : preorder ,
” postorder ” : postorder
}

i f t r a v e r s a l t y p e in t r a v e r s a l f u n c t i o n s :
t r a v e r s a l f u n c t i o n s [ traversal type ] ( s e l f . root )
return s t e p s
return None

c l a s s Graph : #I m p l e m e n t a t i o n o f a graph
def init ( self ) :
s e l f . a d j a c e n c y l i s t = {}
def add edge ( s e l f , s r c , d e s t ) :
i f s r c not in s e l f . a d j a c e n c y l i s t : # A l l t h e noded
are s t o r e d in the adjacency l i s t
s e l f . adjacency list [ src ] = [ ]
i f d e s t not in s e l f . a d j a c e n c y l i s t : # t h e
d e s t i n a t i o n nodes and t h e s o u r c e nodes a r e
stored in the adjacency l i s t
s e l f . a d j a c e n c y l i s t [ dest ] = [ ]
s e l f . a d j a c e n c y l i s t [ s r c ] . append ( d e s t )
s e l f . a d j a c e n c y l i s t [ d e s t ] . append ( s r c )

def g e t d f s s t e p s ( s e l f , s t a r t ) : #Depth f i r s t s e a r c h
t r a v e r s a l o f t h e graph
v i s i t e d = set ( )
steps = [ ]

def d f s ( node ) : #i m p l e m e n t a t i o n o f d f s
i f node not in v i s i t e d :
v i s i t e d . add ( node )
s t e p s . append ( node )
f o r n e i g h b o r in s e l f . a d j a c e n c y l i s t [ node ] :
dfs ( neighbor )

dfs ( start )
return s t e p s

8
def g e t b f s s t e p s ( s e l f , s t a r t ) : # g e t t h e s e t e d t o k e e p
t r a c k o f t h e v i s i t e d nodes and t h e queue t o k e e p
t r a c k o f t h e nodes t o be v i s i t e d
v i s i t e d = set ( )
queue = [ s t a r t ]
steps = [ ]
v i s i t e d . add ( s t a r t )

while queue :
node = queue . pop ( 0 )
s t e p s . append ( node )
f o r n e i g h b o r in s e l f . a d j a c e n c y l i s t [ node ] :
i f n e i g h b o r not in v i s i t e d :
v i s i t e d . add ( n e i g h b o r )
queue . append ( n e i g h b o r )

return s t e p s

def d f s ( s e l f , s t a r t v e r t e x ) : #i m p l e m n t a t i o n o f d e p t h
f i r s t search
v i s i t e d = set ( )
steps = [ ]

def d f s r e c u r s i v e ( v e r t e x ) : #s o l i v i n g i t r e c u r s i v e l y
v i s i t e d . add ( v e r t e x )
s t e p s . append ( v e r t e x )

f o r n e i g h b o r in s e l f . graph [ v e r t e x ] :
i f n e i g h b o r not in v i s i t e d :
d f s r e c u r s i v e ( neighbor )

dfs recursive ( start vertex )


return s t e p s

class SortStep : # s t a r t i n g with s o r t i n g algorithms for the


array
def i n i t ( s e l f , array , comparing=None , swapping=None
):
s e l f . a r r a y = a r r a y . copy ( )

9
s e l f . comparing = comparing i f comparing i s not None
else [ ]
s e l f . swapping = swapping i f swapping i s not None
else [ ]

def g e t s o r t i n g s t e p s ( a r r , a l g o r i t h m=” bubble ” ) : #


implementation of the bubble s o r t

steps = [ ]
a r r a y = a r r . copy ( )

i f a l g o r i t h m == ” bubble ” :
#i m p l e m e n t a t i o n o f t h e b u u b l e s o r t s o r t a l g o r i t h m s .
Swap a d a j c e n t e l e m e n t s i f t h e c u r r e n t e l e m e n t
i s g r e a t e r than t h e n e x t e l e m e n t
n = len ( a r r a y )
f o r i in range ( n ) :
f o r j in range ( 0 , n − i − 1 ) :
# Add comparison s t e p
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) ,
comparing =[ j , j + 1 ] ) )

i f array [ j ] > array [ j + 1 ] :


# Add swap s t e p
array [ j ] , array [ j + 1] = array [ j + 1 ] ,
array [ j ]
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) ,
swapping =[ j , j + 1 ] ) )

e l i f a l g o r i t h m == ” s e l e c t i o n ” :
#i m p l e m e n t a t i o n o f t h e s e l e c t i o n s o r t a l g o r i t h m .
Find t h e minimum e l e m e n t i n t h e a r r a y and swap
i t with the f i r s t element
n = len ( a r r a y )
f o r i in range ( n ) :
min idx = i
f o r j in range ( i + 1 , n ) :
# Add comparison s t e p
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) ,
comparing =[ min idx , j ] ) )

10
i f array [ j ] < array [ min idx ] :
min idx = j

i f m i n i d x != i :
# Add swap s t e p
array [ i ] , array [ min idx ] = array [ min idx ] ,
array [ i ]
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) ,
swapping =[ i , m i n i d x ] ) )
e l i f a l g o r i t h m == ” i n s e r t i o n ” :
#i m p l e m e n t a t i o n o f t h e i n s e r t i o n s o r t a l g o r i t h m .
I n s e r t an e l e m e n t from t h e u n s o r t e d a r r a y t o i t s
correct p o s i t i o n in the sorted
n = len ( a r r a y )
f o r i in range ( 1 , n ) :
key = a r r a y [ i ]
j = i − 1
while j >= 0 and key < a r r a y [ j ] :
# Add comparison s t e p
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) ,
comparing =[ j , j + 1 ] ) )

array [ j + 1] = array [ j ]
j −= 1
a r r a y [ j + 1 ] = key
s t e p s . append ( S o r t S t e p ( a r r a y . copy ( ) , swapping =[ j
+ 1, i ]) )

return s t e p s

3 DataStructureVisualizer
The DataStructureVisualizer file is the graphical interface program that will
be displayed to the user. The main focus of the file is the usage of the Tkinter
library. The library insures that each data structure will be shown correctly
and that the algorithms and the operations will be animated correctly. In
this part we have three main components, the user interface, Visualization,
and button functions.

11
3.1 User interface (UI)
The program has a structured and intuitive layout. Firstly, it starts with the
Data structure selection, which is done with radio buttons between Array,
List, Tree, and graph. Secondly, it shows different operations that you can
do to a specific data structure like to add an element, delete an element and
randomize it. Special buttons like tree traversals and graph traversals only
become available when you press the correct data structure. If we choose the
Array data structure, the sorting algorithms will become available to press.
Below all the different options, the slider which will dictate the animation
speed will be available. Lastly, a button to save the results of the current
traversal or sorting operation into a file for future reference will be available.

3.2 Visualization
The visualization updates dynamically to reflect the state of the current
selected data structure. In the case of the array, the elements are displayed
using rectangle shapes with numerical values inside. The same can be said
for linked list, with the exception of including the arrow symbol to visualize
a pointer. In Binary trees, the nodes and edges are drawn in a hierarchical
manner in order to display the parent-child relationship. In graphs, similar
visualization is also used, using nodes and arrows to symbolize direction.

3.3 Button functions


Each button is linked to a specific function. An example would be the add
element button, which takes this form:
def a d d e l e m e n t ( s e l f ) :
v a l u e = int ( s e l f . g e t u s e r i n p u t ( ” Enter v a l u e t o add : ” ) )
s e l f . s e l e c t e d s t r u c t u r e . add ( v a l u e )
s e l f . visualize ()
This method will prompt the user for an integer value and then will call the
add method for the corresponding data structure.

3.4 Data structure visualizer code


The code that implements all the aforementioned functionalities is displayed
below:

12
#i m p p l e m e n t a t i o n v u s u a k i z a t i o n u s i n g t k i t e r
import t k i n t e r a s tk
from t k i n t e r import ttk , messagebox , s i m p l e d i a l o g #
messagebox used f o r showing message and s i m p l e d i a l o g f o r
t a k i n g i n p u t from u s e r
from d a t a s t r u c t u r e import BinaryTree , g e t s o r t i n g s t e p s ,
Graph #i m p o r t f i r m t h e o t h e r f i l e o f t h e s t r u c u r e s t h a t
w i l l output
import math #math l i b r a r y f o r g r a p h s
import random #random f o r r a n d o m i z i n g t h e d a t a i n t h e
structures
from t k i n t e r import ttk , messagebox , s i m p l e d i a l o g ,
filedialog
class DataStructureVisualizer :
def i n i t ( s e l f , root ) :
s e l f . root = root
s e l f . r o o t . t i t l e ( ” Data S t r u c t u r e V i s u a l i z e r ” )

# Main d a t a s t r u c t u r e v a r i a b l e s
s e l f . c u r r e n t s t r u c t u r e = None
s e l f . data = [ ]
s e l f . b i n a r y t r e e = BinaryTree ( )
s e l f . graph = Graph ( )
s e l f . a n i m a t i o n s p e e d = tk . DoubleVar ( v a l u e =1.0)
s e l f . is animating = False
s e l f . animation steps = [ ]
s e l f . current step = 0

# UI Elements
s e l f . create ui ()
#randomize a r r a y w i l l f i r s t t a k e t h e i n p u t from t h e u s e r
and t h e n randomize t h e a r r a y u s i n g number from 1 t o 100
def r a n d o m i z e a r r a y ( s e l f ) :
count = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ” Enter
number o f e l e m e n t s t o randomize : ” , minvalue =1,
maxvalue =20)
i f count :
s e l f . data = [ random . r a n d i n t ( 1 , 1 0 0 ) f o r in
range ( count ) ]

13
s e l f . update visualization ()

def c r e a t e u i ( s e l f ) :
# C r e a t e a frame f o r s e l e c t i n g d a t a s t r u c t u r e
s t r u c t u r e f r a m e = t t k . LabelFrame ( s e l f . r o o t , t e x t=”
S e l e c t Data S t r u c t u r e ” ) #g i v i n g i t a l a b e l
s t r u c t u r e f r a m e . g r i d ( row=0, column =0, padx =10 , pady
=10 , s t i c k y=” nsew ” ) #s e t t i n g t h e p o s i t i o n o f t h e
frame
#r a d i o b u t t o n s f o r t h e d a t a s t r u c t u r e s
s e l f . s t r u c t u r e v a r = tk . S t r i n g V a r ( v a l u e=” Array ” )
s t r u c t u r e s = [ ” Array ” , ” L i s t ” , ” Tree ” , ”Graph” ]
#i m p l e m e n t i n g t h e r a d i o b u t t o n s
f o r s t r u c t in s t r u c t u r e s :
t t k . Radiobutton ( s t r u c t u r e f r a m e , t e x t=s t r u c t ,
v a r i a b l e= s e l f . s t r u c t u r e v a r ,
v a l u e=s t r u c t , command= s e l f .
c h a n g e s t r u c t u r e ) . pack (
anchor=”w” )

# Frame f o r o p e r a t i o n s
o p e r a t i o n f r a m e = t t k . LabelFrame ( s e l f . r o o t , t e x t=”
Operations ” )
o p e r a t i o n f r a m e . g r i d ( row=1, column =0, padx =10 , pady
=10 , s t i c k y=” nsew ” )

# B u t t o n s f o r a d d i n g and d e l e t i n g e l e m e n t s
t t k . Button ( o p e r a t i o n f r a m e , t e x t=”Add Element ” ,
command= s e l f . a d d e l e m e n t ) . pack ( f i l l =”x” ,
pady=5)
t t k . Button ( o p e r a t i o n f r a m e , t e x t=” D e l e t e Element ” ,
command= s e l f . d e l e t e e l e m e n t ) . pack ( f i l l =”x” ,
pady=5)

# Randomize b u t t o n ( dynamic f u n c t i o n a l i t y )
s e l f . r a n d o m i z e b u t t o n = t t k . Button ( o p e r a t i o n f r a m e ,
t e x t=” Randomize ” , command= s e l f .
randomize structure )
s e l f . r a n d o m i z e b u t t o n . pack ( f i l l =”x” , pady=5)

14
# Tree t r a v e r s a l b u t t o n s
s e l f . t r e e b u t t o n s f r a m e = t t k . LabelFrame (
o p e r a t i o n f r a m e , t e x t=” Tree T r a v e r s a l s ” )
s e l f . t r e e b u t t o n s f r a m e . pack ( f i l l =”x” , pady=5)

t t k . Button ( s e l f . t r e e b u t t o n s f r a m e , t e x t=” I n o r d e r ” ,
command=lambda : s e l f . t r a v e r s e t r e e ( ” i n o r d e r
” ) ) . pack ( f i l l =”x” , pady=2)
t t k . Button ( s e l f . t r e e b u t t o n s f r a m e , t e x t=” P r e o r d e r ”
,
command=lambda : s e l f . t r a v e r s e t r e e ( ”
p r e o r d e r ” ) ) . pack ( f i l l =”x” , pady=2)
t t k . Button ( s e l f . t r e e b u t t o n s f r a m e , t e x t=” P o s t o r d e r
”,
command=lambda : s e l f . t r a v e r s e t r e e ( ”
p o s t o r d e r ” ) ) . pack ( f i l l =”x” , pady=2)

# Sorting buttons
s e l f . s o r t b u t t o n s f r a m e = t t k . LabelFrame (
o p e r a t i o n f r a m e , t e x t=” S o r t i n g ” )
s e l f . s o r t b u t t o n s f r a m e . pack ( f i l l =”x” , pady=5)

t t k . Button ( s e l f . s o r t b u t t o n s f r a m e , t e x t=” Bubble


Sort ” ,
command=lambda : s e l f . s t a r t s o r t i n g ( ” bubble ”
) ) . pack ( f i l l =”x” , pady=2)
t t k . Button ( s e l f . s o r t b u t t o n s f r a m e , t e x t=” S e l e c t i o n
Sort ” ,
command=lambda : s e l f . s t a r t s o r t i n g ( ”
s e l e c t i o n ” ) ) . pack ( f i l l =”x” , pady=2)
t t k . Button ( s e l f . s o r t b u t t o n s f r a m e , t e x t=” I n s e r t i o n
Sort ” ,
command=lambda : s e l f . s t a r t s o r t i n g ( ”
i n s e r t i o n ” ) ) . pack ( f i l l =”x” , pady=2)

# Graph−s p e c i f i c b u t t o n s
s e l f . g r a p h b u t t o n s f r a m e = t t k . LabelFrame (
o p e r a t i o n f r a m e , t e x t=”Graph T r a v e r s a l s ” )
s e l f . g r a p h b u t t o n s f r a m e . pack ( f i l l =”x” , pady=5)

15
t t k . Button ( s e l f . g r a p h b u t t o n s f r a m e , t e x t=”Add Edge
”,
command= s e l f . add edge ) . pack ( f i l l =”x” , pady
=5)
t t k . Button ( s e l f . g r a p h b u t t o n s f r a m e , t e x t=”DFS” ,
command=lambda : s e l f . t r a v e r s e g r a p h ( ” d f s ” ) )
. pack ( f i l l =”x” , pady=2)
t t k . Button ( s e l f . g r a p h b u t t o n s f r a m e , t e x t=”BFS” ,
command=lambda : s e l f . t r a v e r s e g r a p h ( ” b f s ” ) )
. pack ( f i l l =”x” , pady=2)

# Animation s p e e d c o n t r o l
s p e e d f r a m e = t t k . LabelFrame ( o p e r a t i o n f r a m e , t e x t=
” Animation Speed ” )
s p e e d f r a m e . pack ( f i l l =”x” , pady=5)

s p e e d s l i d e r = t t k . S c a l e ( s p e e d f r a m e , f r o m =0.1 , t o
=2.0 ,
v a r i a b l e= s e l f .
a n i m a t i o n s p e e d , o r i e n t=
” horizontal ”)
s p e e d s l i d e r . pack ( f i l l =”x” , pady=5)

# Save t o f i l e b u t t o n
t t k . Button ( o p e r a t i o n f r a m e , t e x t=” Save T r a v e r s a l t o
F i l e ” , command= s e l f . s a v e t o f i l e ) . pack ( f i l l =”x”
, pady=5)

# Frame f o r v i s u a l i z i n g t h e s t r u c t u r e
s e l f . v i s u a l f r a m e = t t k . LabelFrame ( s e l f . r o o t , t e x t=
” Visualization ”)
s e l f . v i s u a l f r a m e . g r i d ( row=0, column =1, rowspan =2,
padx =10 , pady =10 , s t i c k y=” nsew ” )

s e l f . v i s u a l c a n v a s = tk . Canvas ( s e l f . v i s u a l f r a m e ,
bg=” w h i t e ” , h e i g h t =400 , width =600)
s e l f . v i s u a l c a n v a s . pack ( f i l l =” both ” , expand=True )

# Configure grid weights


s e l f . r o o t . g r i d c o l u m n c o n f i g u r e ( 1 , w e i g h t =1)

16
s e l f . r o o t . g r i d r o w c o n f i g u r e ( 1 , w e i g h t =1)

# Update b u t t o n s t a t e s b a s e d on t h e i n i t i a l
structure
s e l f . update button states ()
def s a v e t o f i l e ( s e l f ) :
i f not s e l f . a n i m a t i o n s t e p s :
messagebox . s h o w i n f o ( ” Save ” , ”No t r a v e r s a l o r
s o r t i n g s t e p s a v a i l a b l e to save . ” )
return
f i l e p a t h = f i l e d i a l o g . asksaveasfilename (
d e f a u l t e x t e n s i o n=” . t x t ” ,
filetypes
=[( ”
Text
files”,
” ∗. txt
”) , (”
All
files”,
” ∗.∗ ”)
])
i f not f i l e p a t h :
return

try :
with open ( f i l e p a t h , ”w” ) a s f i l e :
f o r s t e p in s e l f . a n i m a t i o n s t e p s :
i f isinstance ( step , str ) :
f i l e . w r i t e ( s t e p + ” \n” )
e l i f hasattr ( s t e p , ’ v a l u e ’ ) :
f i l e . w r i t e ( s t r ( s t e p . v a l u e ) + ” \n” )
messagebox . s h o w i n f o ( ” Save ” , ” T r a v e r s a l s t e p s
saved s u c c e s s f u l l y ! ” )
except E x c e p t i o n a s e :
messagebox . s h o w e r r o r ( ” E r r o r ” , f ” F a i l e d t o s a v e
t h e f i l e : { e }” )
def r a n d o m i z e s t r u c t u r e ( s e l f ) :
i f s e l f . c u r r e n t s t r u c t u r e == ” Array ” :

17
count = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ” Enter
number o f e l e m e n t s t o randomize : ” , minvalue
=1, maxvalue =20)
i f count :
s e l f . data = [ random . r a n d i n t ( 1 , 1 0 0 ) f o r
in range ( count ) ]
s e l f . update visualization ()

e l i f s e l f . c u r r e n t s t r u c t u r e == ” L i s t ” :
count = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ” Enter
number o f e l e m e n t s t o randomize : ” , minvalue
=1, maxvalue =20)
i f count :
s e l f . data = [ random . r a n d i n t ( 1 , 1 0 0 ) f o r
in range ( count ) ]
s e l f . update visualization ()

e l i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
count = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ” Enter
number o f e l e m e n t s t o randomize : ” , minvalue
=1, maxvalue =20)
i f count :
s e l f . b i n a r y t r e e = BinaryTree ( )
s e l f . data = [ ]
for in range ( count ) :
v a l u e = random . r a n d i n t ( 1 , 1 0 0 )
s e l f . binary tree . i n s e r t ( value )
s e l f . data . append ( v a l u e )
s e l f . update visualization ()

e l i f s e l f . c u r r e n t s t r u c t u r e == ”Graph” :
num nodes = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ”
Enter number o f nodes : ” , minvalue =2,
maxvalue =20)
num edges = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ”
Enter number o f e d g e s : ” , minvalue =1,
maxvalue=num nodes ∗ ( num nodes − 1 ) // 2 )
i f num nodes and num edges :
s e l f . graph = Graph ( )
nodes = [ s t r ( i ) f o r i in range ( num nodes ) ]

18
f o r i in range ( num nodes ) :
s e l f . graph . a d j a c e n c y l i s t [ nodes [ i ] ] =
[]
s e l f . data = nodes
edge count = 0
while e d g e c o u n t < num edges :
s r c = random . c h o i c e ( nodes )
d e s t = random . c h o i c e ( nodes )
i f s r c != d e s t and d e s t not in s e l f .
graph . a d j a c e n c y l i s t [ s r c ] :
s e l f . graph . add edge ( s r c , d e s t )
e d g e c o u n t += 1

s e l f . update visualization ()
def g e n e r a t e r a n d o m e l e m e n t s ( s e l f ) :
import random
count = s i m p l e d i a l o g . a s k i n t e g e r ( ” Input ” , ” Enter
number o f e l e m e n t s t o g e n e r a t e : ” , minvalue =1,
maxvalue =20)
i f count :
s e l f . data = [ ]
for in range ( count ) :
v a l u e = random . r a n d i n t ( 1 , 1 0 0 )
s e l f . data . append ( v a l u e )
i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
s e l f . binary tree . i n s e r t ( value )
s e l f . update visualization ()

def u p d a t e b u t t o n s t a t e s ( s e l f ) :
i s t r e e = s e l f . c u r r e n t s t r u c t u r e == ” Tree ”
i s a r r a y = s e l f . c u r r e n t s t r u c t u r e == ” Array ”
i s g r a p h = s e l f . c u r r e n t s t r u c t u r e == ”Graph”

# Enable / d i s a b l e t r e e t r a v e r s a l b u t t o n s
f o r c h i l d in s e l f . t r e e b u t t o n s f r a m e . w i n f o c h i l d r e n
() :
c h i l d [ ” s t a t e ” ] = ” normal ” i f i s t r e e e l s e ”
disabled ”

# Enable / d i s a b l e s o r t i n g b u t t o n s

19
f o r c h i l d in s e l f . s o r t b u t t o n s f r a m e . w i n f o c h i l d r e n
() :
c h i l d [ ” s t a t e ” ] = ” normal ” i f i s a r r a y e l s e ”
disabled ”

# Enable / d i s a b l e graph b u t t o n s
f o r c h i l d in s e l f . g r a p h b u t t o n s f r a m e .
winfo children () :
c h i l d [ ” s t a t e ” ] = ” normal ” i f i s g r a p h e l s e ”
disabled ”
def a d d e l e m e n t ( s e l f ) :
e l e m e n t = s i m p l e d i a l o g . a s k s t r i n g ( ” Input ” , ” Enter
e l e m e n t t o add : ” )
i f e l e m e n t and e l e m e n t . i s d i g i t ( ) :
v a l u e = int ( e l e m e n t )
s e l f . data . append ( v a l u e )
i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
s e l f . binary tree . i n s e r t ( value )
s e l f . update visualization ()
e l i f element :
messagebox . s h o w e r r o r ( ” E r r o r ” , ” P l e a s e e n t e r a
v a l i d number . ” )

def d e l e t e e l e m e n t ( s e l f ) :
e l e m e n t = s i m p l e d i a l o g . a s k s t r i n g ( ” Input ” , ” Enter
element to d e l e t e : ” )
i f e l e m e n t and e l e m e n t . i s d i g i t ( ) :
v a l u e = int ( e l e m e n t )
i f v a l u e in s e l f . data :
s e l f . data . remove ( v a l u e )
i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
s e l f . b i n a r y t r e e = BinaryTree ( )
f o r v a l in s e l f . data :
s e l f . binary tree . i n s e r t ( val )
s e l f . update visualization ()
else :
messagebox . s h o w e r r o r ( ” E r r o r ” , ” Element not
found i n t h e data s t r u c t u r e . ” )

def s t a r t s o r t i n g ( s e l f , a l g o r i t h m ) :

20
i f not s e l f . data :
messagebox . s h o w i n f o ( ” S o r t ” , ”The data s t r u c t u r e
i s empty . ” )
return

if s e l f . is animating :
return

s e l f . i s a n i m a t i n g = True
s e l f . a n i m a t i o n s t e p s = g e t s o r t i n g s t e p s ( s e l f . data .
copy ( ) , a l g o r i t h m )
s e l f . current step = 0
s e l f . animate sort step ()

def a n i m a t e s o r t s t e p ( s e l f ) :
i f s e l f . c u r r e n t s t e p < len ( s e l f . a n i m a t i o n s t e p s ) :
step = s e l f . animation steps [ s e l f . current step ]
s e l f . data = s t e p . a r r a y . copy ( )
s e l f . update visualization ()
s e l f . v i s u a l i z e a r r a y ( s t e p . comparing , s t e p .
swapping )

s e l f . c u r r e n t s t e p += 1
d e l a y = int ( 1 0 0 0 / s e l f . a n i m a t i o n s p e e d . g e t ( ) )
s e l f . r o o t . a f t e r ( dela y , s e l f . a n i m a t e s o r t s t e p )
else :
s e l f . is animating = False
s e l f . update visualization ()

def t r a v e r s e t r e e ( s e l f , t r a v e r s a l t y p e ) :
i f not s e l f . b i n a r y t r e e . r o o t :
messagebox . s h o w i n f o ( ” T r a v e r s e ” , ”The t r e e i s
empty . ” )
return

if s e l f . is animating :
return

s e l f . i s a n i m a t i n g = True

21
s e l f . animation steps = s e l f . binary tree .
get traversal steps ( traversal type )
s e l f . current step = 0
s e l f . animate traversal step ()

def a n i m a t e t r a v e r s a l s t e p ( s e l f ) :
i f s e l f . c u r r e n t s t e p < len ( s e l f . a n i m a t i o n s t e p s ) :
# R e s e t a l l nodes t o o r i g i n a l c o l o r
f o r item in s e l f . v i s u a l c a n v a s . f i n d w i t h t a g ( ”
node ” ) :
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
lightcoral ”)

# H i g h l i g h t c u r r e n t node
current node = s e l f . animation steps [ s e l f .
current step ]
node items = s e l f . visual canvas . find withtag ( f ”
node { c u r r e n t n o d e . v a l u e }” )
f o r item in n o d e i t e m s :
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
yellow ”)

s e l f . c u r r e n t s t e p += 1
d e l a y = int ( 1 0 0 0 / s e l f . a n i m a t i o n s p e e d . g e t ( ) )
s e l f . r o o t . a f t e r ( dela y , s e l f .
animate traversal step )
else :
s e l f . is animating = False
s e l f . root . a f t e r (500 , s e l f . r e s e t n o d e c o l o r s )

def r e s e t n o d e c o l o r s ( s e l f ) :
f o r item in s e l f . v i s u a l c a n v a s . f i n d w i t h t a g ( ” node ” )
:
i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
lightcoral ”)
e l i f s e l f . c u r r e n t s t r u c t u r e == ” Array ” :
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
lightblue ”)
e l i f s e l f . c u r r e n t s t r u c t u r e == ” L i s t ” :

22
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
lightgreen ”)

def u p d a t e v i s u a l i z a t i o n ( s e l f ) :
s e l f . visual canvas . delete (” a l l ”)
i f s e l f . c u r r e n t s t r u c t u r e == ” Array ” :
s e l f . visualize array ()
e l i f s e l f . c u r r e n t s t r u c t u r e == ” L i s t ” :
s e l f . v i s u a l i z e l i s t ()
e l i f s e l f . c u r r e n t s t r u c t u r e == ” Tree ” :
s e l f . visualize tree ()
e l i f s e l f . c u r r e n t s t r u c t u r e == ”Graph” :
s e l f . visualize graph ()

def v i s u a l i z e a r r a y ( s e l f , comparing=None , swapping=None


):
x s t a r t = 50
y s t a r t = 200
box width = 50
b o x h e i g h t = 50
comparing = comparing or [ ]
swapping = swapping or [ ]

# Draw g r i d l i n e s
f o r i in range ( len ( s e l f . data ) + 1 ) :
x = x s t a r t + i ∗ box width
s e l f . v i s u a l c a n v a s . c r e a t e l i n e (x , y s t a r t − 10 ,
x , y start +
box height +
10 ,
f i l l =” l i g h t g r a y ” )

s e l f . visual canvas . create line ( x start , y start −


10 ,
x s t a r t + len ( s e l f .
data ) ∗ box width ,
y s t a r t − 1 0 , f i l l =”
lightgray ”)
s e l f . visual canvas . create line ( x start , y start +
box height + 10 ,

23
x s t a r t + len ( s e l f .
data ) ∗ box width ,
y start + box height +
1 0 , f i l l =”
lightgray ”)

for i , e l e m e n t in enumerate ( s e l f . data ) :


x0 = x s t a r t + i ∗ box width
y0 = y start
x1 = x0 + box width
y1 = y0 + b o x h e i g h t

# Determine box c o l o r b a s e d on o p e r a t i o n
i f i in swapping :
f i l l c o l o r = ”#FF6B6B”
o u t l i n e c o l o r = ”#FF0000”
outline width = 3
e l i f i in comparing :
f i l l c o l o r = ”#4ECDC4”
o u t l i n e c o l o r = ”#45B7AF”
outline width = 3
else :
f i l l c o l o r = ” lightblue ”
o u t l i n e c o l o r = ””
outline width = 1

# Draw shadow
shadow offset = 3
s e l f . v i s u a l c a n v a s . c r e a t e r e c t a n g l e ( x0 +
s h a d o w o f f s e t , y0 + s h a d o w o f f s e t ,
x1 +
shadow offset
, y1 +
shadow offset
,
f i l l =”#CCCCCC”
, o u t l i n e=”
”)

# Draw main box

24
s e l f . v i s u a l c a n v a s . c r e a t e r e c t a n g l e ( x0 , y0 , x1 ,
y1 ,
f i l l=
fill color ,
o u t l i n e=
outline color
,
width=
outline width
, t a g s =(”
node ” , f ”
node {
element }” ) )

# Draw e l e m e n t v a l u e
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( ( x0 + x1 ) / 2 , (
y0 + y1 ) / 2 ,
t e x t=s t r ( e l e m e n t ) ,
f o n t =(” A r i a l ” , 1 2 ,
” bold ” ) )

# Draw i n d e x numbers
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( ( x0 + x1 ) / 2 ,
y0 − 2 0 ,
t e x t=s t r ( i ) ,
f o n t =(” A r i a l ” , 1 0 )
)

# Add o p e r a t i o n i n d i c a t o r s
i f i in comparing :
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( ( x0 + x1 ) /
2 , y1 + 2 0 ,
t e x t=”
comparing ” ,
f o n t =(” A r i a l ” ,
8) ,
f i l l =”#45B7AF”
)
e l i f i in swapping :

25
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( ( x0 + x1 ) /
2 , y1 + 2 0 ,
t e x t=” swapping
”,
f o n t =(” A r i a l ” ,
8) ,
f i l l =”#FF0000”
)

def v i s u a l i z e l i s t ( s e l f ) :
x s t a r t = 50
y s t a r t = 200
box width = 50
b o x h e i g h t = 50
a r r o w l e n g t h = 30

for i , e l e m e n t in enumerate ( s e l f . data ) :


x0 = x s t a r t + i ∗ ( box width + a r r o w l e n g t h )
y0 = y start
x1 = x0 + box width
y1 = y0 + b o x h e i g h t

# Draw node shadow


shadow offset = 3
s e l f . v i s u a l c a n v a s . c r e a t e r e c t a n g l e ( x0 +
s h a d o w o f f s e t , y0 + s h a d o w o f f s e t ,
x1 +
shadow offset
, y1 +
shadow offset
,
f i l l =”#CCCCCC”
, o u t l i n e=”
”)

# Draw node
s e l f . v i s u a l c a n v a s . c r e a t e r e c t a n g l e ( x0 , y0 , x1 ,
y1 ,
f i l l =”
lightgreen ”

26
,
t a g s =(” node ” ,
f ” node {
element }” ) )

# Draw v a l u e
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( ( x0 + x1 ) / 2 , (
y0 + y1 ) / 2 ,
t e x t=s t r ( e l e m e n t ) ,
f o n t =(” A r i a l ” , 1 2 ,
” bold ” ) )

# Draw arrow t o n e x t node


i f i < len ( s e l f . data ) − 1 :
a r r o w x 0 = x1
a r r o w x 1 = x1 + a r r o w l e n g t h
a r r o w y = ( y0 + y1 ) / 2

# Draw arrow l i n e
s e l f . v i s u a l c a n v a s . c r e a t e l i n e ( arrow x0 ,
arrow y ,
arrow x1 ,
arrow y ,
arrow=” l a s t ” ,
width =2)

def v i s u a l i z e t r e e ( s e l f ) :
i f not s e l f . data :
return

def c a l c u l a t e p o s i t i o n ( index , l e v e l , x o f f s e t ) :
””” C a l c u l a t e t h e x , y c o o r d i n a t e s f o r a node
b a s e d on i t s l e v e l and p o s i t i o n . ”””
y = 50 + l e v e l ∗ 80
x = 300 + x o f f s e t
return x , y

def draw node ( x , y , va lue , p a r e n t x=None , p a r e n t y=


None ) :

27
”””Draw a t r e e node and i t s c o n n e c t i o n t o
p a r e n t i f e x i s t s . ”””
r a d i u s = 20

# Draw c o n n e c t i o n t o p a r e n t
i f p a r e n t x i s not None and p a r e n t y i s not
None :
s e l f . v i s u a l c a n v a s . c r e a t e l i n e ( parent x ,
parent y + radius ,
x , y − radius ,
width =2)

# Draw node shadow


shadow offset = 3
s e l f . visual canvas . create oval (x − radius +
shadow offset ,
y − radius +
shadow offset ,
x + radius +
shadow offset ,
y + radius +
shadow offset ,
f i l l =”#CCCCCC” ,
o u t l i n e=” ” )

# Draw node
s e l f . visual canvas . c r e a t e o v a l (x − radius , y −
radius ,
x + radius , y +
radius ,
f i l l =” l i g h t c o r a l ” ,
t a g s =(” node ” , f ”
node { v a l u e } ” ) )

# Draw v a l u e
s e l f . visual canvas . create text (x , y ,
t e x t=s t r ( v a l u e ) ,
f o n t =(” A r i a l ” , 1 2 ,
” bold ” ) )

28
def v i s u a l i z e l e v e l o r d e r ( ) :
””” V i s u a l i z e t h e t r e e u s i n g l e v e l −o r d e r
t r a v e r s a l . ”””
i f not s e l f . data :
return

# C a l c u l a t e t h e maximum l e v e l
level count = 0
nodes at current level = 1
t o t a l n o d e s = len ( s e l f . data )
while t o t a l n o d e s > 0 :
t o t a l n o d e s −= n o d e s a t c u r r e n t l e v e l
n o d e s a t c u r r e n t l e v e l ∗= 2
l e v e l c o u n t += 1

# Draw each l e v e l
node index = 0
f o r l e v e l in range ( l e v e l c o u n t ) :
n o d e s i n l e v e l = min( 2 ∗∗ l e v e l , len ( s e l f .
data ) − n o d e i n d e x )
l e v e l w i d t h = 2 ∗∗ ( l e v e l c o u n t − 1 ) ∗ 60
# Base s p a c i n g

f o r i in range ( n o d e s i n l e v e l ) :
i f n o d e i n d e x >= len ( s e l f . data ) :
break

# Calculate position
x o f f s e t = ( i − n o d e s i n l e v e l /2 + 0 . 5 )
∗ ( l e v e l w i d t h / ( 2 ∗∗ l e v e l ) )
x , y = calculate position ( i , level ,
x offset )

# C a l c u l a t e p a r e n t p o s i t i o n f o r drawing
connection
i f node index > 0:
p a r e n t i n d e x = ( n o d e i n d e x − 1 ) //
2
parent level = level − 1

29
p a r e n t i = p a r e n t i n d e x − ( 2 ∗∗
p a r e n t l e v e l − 1)
p a r e n t x o f f s e t = ( p a r e n t i − ( 2 ∗∗
p a r e n t l e v e l ) /2 + 0 . 5 ) ∗ (
l e v e l w i d t h / ( 2 ∗∗ p a r e n t l e v e l
))
parent x , parent y =
calculate position ( parent i ,
parent level , parent x offset )
else :
p a r e n t x , p a r e n t y = None , None

# Draw t h e node
draw node ( x , y , s e l f . data [ n o d e i n d e x ] ,
parent x , parent y )
n o d e i n d e x += 1

# Visualize the tree


visualize level order ()
def c h a n g e s t r u c t u r e ( s e l f ) :
s e l f . current structure = s e l f . structure var . get
()
s e l f . data = [ ]
s e l f . b i n a r y t r e e = BinaryTree ( )
s e l f . graph = Graph ( )
s e l f . update button states ()
s e l f . update visualization ()

def add edge ( s e l f ) :


s r c = s i m p l e d i a l o g . a s k s t r i n g ( ” Input ” , ” Enter s o u r c e
node : ” )
d e s t = s i m p l e d i a l o g . a s k s t r i n g ( ” Input ” , ” Enter
d e s t i n a t i o n node : ” )
i f s r c and d e s t :
s e l f . graph . add edge ( s r c , d e s t )
s e l f . update visualization ()

def t r a v e r s e g r a p h ( s e l f , t r a v e r s a l t y p e ) :
i f not s e l f . graph . a d j a c e n c y l i s t :

30
messagebox . s h o w i n f o ( ”Graph” , ”The graph i s
empty . ” )
return

if s e l f . is animating :
return

s t a r t n o d e = s i m p l e d i a l o g . a s k s t r i n g ( ” Input ” , ” Enter
s t a r t node : ” )
i f s t a r t n o d e not in s e l f . graph . a d j a c e n c y l i s t :
messagebox . s h o w e r r o r ( ” E r r o r ” , ” S t a r t node not
found i n t h e graph . ” )
return

s e l f . i s a n i m a t i n g = True
i f t r a v e r s a l t y p e == ” d f s ” :
s e l f . a n i m a t i o n s t e p s = s e l f . graph . g e t d f s s t e p s
( start node )
e l i f t r a v e r s a l t y p e == ” b f s ” :
s e l f . a n i m a t i o n s t e p s = s e l f . graph . g e t b f s s t e p s
( start node )

s e l f . current step = 0
s e l f . animate graph step ()

def a n i m a t e g r a p h s t e p ( s e l f ) :
i f s e l f . c u r r e n t s t e p < len ( s e l f . a n i m a t i o n s t e p s ) :
current node = s e l f . animation steps [ s e l f .
current step ]

# H i g h l i g h t c u r r e n t node
s e l f . visual canvas . delete (” highlight ”)
node items = s e l f . visual canvas . find withtag ( f ”
node { c u r r e n t n o d e }” )
f o r item in n o d e i t e m s :
s e l f . v i s u a l c a n v a s . i t e m c o n f i g ( item , f i l l =”
yellow ”)

s e l f . c u r r e n t s t e p += 1
d e l a y = int ( 1 0 0 0 / s e l f . a n i m a t i o n s p e e d . g e t ( ) )

31
s e l f . r o o t . a f t e r ( dela y , s e l f . a n i m a t e g r a p h s t e p )
else :
s e l f . is animating = False
s e l f . root . a f t e r (500 , s e l f . r e s e t n o d e c o l o r s )

def v i s u a l i z e g r a p h ( s e l f ) :
s e l f . visual canvas . delete (” a l l ”)
n o d e p o s i t i o n s = {}
r a d i u s = 20
c a n v a s w i d t h = 600
c a n v a s h e i g h t = 400
n o d e c o u n t = len ( s e l f . graph . a d j a c e n c y l i s t )
a n g l e s t e p = 2 ∗ math . p i / n o d e c o u n t i f n o d e c o u n t
e l s e 0 # Angle s t e p i n r a d i a n s

# C a l c u l a t e node p o s i t i o n s i n a c i r c u l a r l a y o u t
f o r i , node in enumerate ( s e l f . graph . a d j a c e n c y l i s t .
keys ( ) ) :
angle = angle step ∗ i
x = c a n v a s w i d t h // 2 + 150 ∗ math . c o s ( a n g l e )
y = c a n v a s h e i g h t // 2 + 150 ∗ math . s i n ( a n g l e )
n o d e p o s i t i o n s [ node ] = ( x , y )

# Draw node
s e l f . visual canvas . c r e a t e o v a l (x − radius , y −
radius , x + radius , y + radius ,
f i l l =” l i g h t b l u e ” ,
t a g s =(” node ” , f ”
node { node } ” ) )
s e l f . v i s u a l c a n v a s . c r e a t e t e x t ( x , y , t e x t=s t r (
node ) , f o n t =(” A r i a l ” , 1 2 , ” b o l d ” ) )

# Draw e d g e s
f o r s r c , n e i g h b o r s in s e l f . graph . a d j a c e n c y l i s t .
items () :
f o r d e s t in n e i g h b o r s :
x1 , y1 = n o d e p o s i t i o n s [ s r c ]
x2 , y2 = n o d e p o s i t i o n s [ d e s t ]
s e l f . v i s u a l c a n v a s . c r e a t e l i n e ( x1 , y1 , x2 ,
y2 , arrow=” l a s t ” )

32
if name == ” m a i n ” :
r o o t = tk . Tk ( )
app = D a t a S t r u c t u r e V i s u a l i z e r ( r o o t )
r o o t . mainloop ( )

4 A general look into the program


In this part, multiple screenshots are captured in order to display better all
the functionalities of the program.

Figure 1: The starting look of the application

33
Figure 2: The adding of elements

Figure 3: The deleting of elements

Figure 4: Randomizing an array

34
Figure 5: Random array

Figure 6: Bubble sort visualized

Figure 7: Linked List

35
Figure 8: Binary tree

Figure 9: Inorder traversal

Figure 10: Inorder traversal saved in the file

36
Figure 11: Graphs visualized

Figure 12: DFS visualized

Figure 13: DFS traversal saved in the file

37

You might also like