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

Algorithms and Data Structures

Uploaded by

zam.pfe
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
18 views

Algorithms and Data Structures

Uploaded by

zam.pfe
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Contents

0.1 Big O Notation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3


0.1.1 Time Complexity . . . . . . . . . . . . . . . . . . . . . . . 3
0.1.2 Space Complexity . . . . . . . . . . . . . . . . . . . . . . 3
0.2 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
0.2.1 Static vs Dynamic Arrays . . . . . . . . . . . . . . . . . . 4
0.2.2 Operations on Arrays . . . . . . . . . . . . . . . . . . . . 4
0.3 Types of Linked Lists . . . . . . . . . . . . . . . . . . . . . . . . 5
0.3.1 Singly Linked List . . . . . . . . . . . . . . . . . . . . . . 5
0.3.2 Doubly Linked List . . . . . . . . . . . . . . . . . . . . . . 5
0.3.3 Circular Linked Lists . . . . . . . . . . . . . . . . . . . . . 5
0.4 Singly Linked List Operations . . . . . . . . . . . . . . . . . . . . 5
0.4.1 isEmpty() . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
0.4.2 AddLast(item) . . . . . . . . . . . . . . . . . . . . . . . . 6
0.4.3 AddFirst(item) . . . . . . . . . . . . . . . . . . . . . . . . 6
0.4.4 indexOf(item) o(n) . . . . . . . . . . . . . . . . . . . . . . 6
0.4.5 contains(item) O(n) . . . . . . . . . . . . . . . . . . . . . 6
0.4.6 removeFirst() . . . . . . . . . . . . . . . . . . . . . . . . . 6
0.4.7 getPrevious(node) . . . . . . . . . . . . . . . . . . . . . . 7
0.4.8 removeLast() . . . . . . . . . . . . . . . . . . . . . . . . . 7
0.4.9 removeItem(value) . . . . . . . . . . . . . . . . . . . . . . 7
0.4.10 Reverse() . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
0.4.11 getKthFromEnd(k) . . . . . . . . . . . . . . . . . . . . . . 8
0.5 Arrays vs Linked List: . . . . . . . . . . . . . . . . . . . . . . . . 9
0.6 Stacks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
0.6.1 Dynamic Representation . . . . . . . . . . . . . . . . . . . 9
0.6.2 Array Representation . . . . . . . . . . . . . . . . . . . . 10
0.7 Queue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
0.7.1 Array Representation . . . . . . . . . . . . . . . . . . . . 12
0.7.2 Implementation with stack . . . . . . . . . . . . . . . . . 13
0.8 Priority qeueu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
0.8.1 Array representatuion . . . . . . . . . . . . . . . . . . . . 15
0.9 Hash tables (Dictionaries) . . . . . . . . . . . . . . . . . . . . . . 16
0.9.1 Hash tables operations . . . . . . . . . . . . . . . . . . . . 16
0.10 Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
0.10.1 Sets operations . . . . . . . . . . . . . . . . . . . . . . . . 17

1
2 CONTENTS

1 Non-linear data structure 19


1.1 Trees . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.2 Binary tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.2.1 Traversal tree . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.2.2 Height and depth of tree node . . . . . . . . . . . . . . . 22
1.2.3 Minimum O(n) . . . . . . . . . . . . . . . . . . . . . . . . 22
1.2.4 Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.2.5 Get nodes at k distance . . . . . . . . . . . . . . . . . . . 23
1.3 Binary search tree . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.3.1 complexity of operations . . . . . . . . . . . . . . . . . . . 24
1.3.2 Operations . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.3.3 Check if the tree is binary search tree . . . . . . . . . . . 25
1.4 AVL Tree . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4.1 Balance Factor . . . . . . . . . . . . . . . . . . . . . . . . 26
1.4.2 Insert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.5 Heap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5.1 Heap representation . . . . . . . . . . . . . . . . . . . . . 28
1.5.2 Operations . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.5.3 Sort values with ”SortHeap” . . . . . . . . . . . . . . . . 31
1.5.4 Priority queue with heap . . . . . . . . . . . . . . . . . . 32
1.5.5 Find k largest value . . . . . . . . . . . . . . . . . . . . . 32
1.6 Graphs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
1.6.1 Implementation of graph in code . . . . . . . . . . . . . . 33
1.6.2 Graph operations . . . . . . . . . . . . . . . . . . . . . . . 34
1.6.3 Graph depth first traversal . . . . . . . . . . . . . . . . . 36
1.6.4 Level order traversal . . . . . . . . . . . . . . . . . . . . . 37
1.6.5 Topological sorting . . . . . . . . . . . . . . . . . . . . . . 37
1.6.6 Detect cycle . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.7 Weighted and non directed graph . . . . . . . . . . . . . . . . . . 39
1.7.1 Implementation . . . . . . . . . . . . . . . . . . . . . . . . 39
1.7.2 Detect cycle . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.8 graph shortest path . . . . . . . . . . . . . . . . . . . . . . . . . . 41
0.1. BIG O NOTATION 3

0.1 Big O Notation


Big O notation is used to describe the performance of an algorithm, specifically
its time or space complexity in relation to the input size.

0.1.1 Time Complexity


Time complexity measures the amount of time an algorithm takes to complete
as a function of the length of the input.

Instructions
Each instruction is considered to have a constant time complexity, denoted as
O(1).
1 < instruction1 > O (1)
2 < instruction2 > O (1)

The overall time complexity for these instructions is O(1 + 1) = O(2) ⇒ O(1)
because O(constant) = O(1).

Loops
For loops, we consider the number of iterations in each case.
1 for ( i = 0; i < array . length ; i ++) [ n times ]
2 < instruction > [1 time ]
3 < instruction > [1 time ]

This will be O((1 + 1) ∗ n) = O(2n) ⇒ O(n).

Nested Loops

1 for ( i = 0; i < array . length ; i ++) [ n times ]


2 for ( j = 0; j < array . length ; j ++) [ m times ]
3 < instruction > [1 time ]
4 < instruction > [1 time ]

This will be:


C = n · ((1 + 1) · m) = 2 · n · m = O(n · m) = O(n2 ) (if n = m)

0.1.2 Space Complexity


We count the space used by our variables:
• int i; ⇒ O(1)
• String[] a = new String[10]; ⇒ O(10) ⇒ O(1)
Assuming that we have a variable t as the input table of the function:
• String[] a = new String[t.length]; ⇒ O(n)
4 CONTENTS

0.2 Arrays
Arrays are used when the size of our data is known.

0.2.1 Static vs Dynamic Arrays


A dynamic array can grow or shrink automatically, but a static array has a fixed
size.

0.2.2 Operations on Arrays


Lookup by Index

Accessing an element by its index:

C = O(1)

Lookup by Value

In the worst case, the value is at the last position of the array:

C = O(n)

Inserting a Value

To insert a value at a specific index:

C = O(1)

In dynamic arrays, if the array is full, we must increase its size. This involves
creating a new array with a larger size and copying all old array values to the
new array:
C = O(n)
0.3. TYPES OF LINKED LISTS 5

Removing an Item from an Array

To remove an item from an array, we shift the subsequent items to the left,
replacing each element array[i] with array[i+1] starting from the removal index.
In the worst case, when removing the first item, we iterate n − 1 times:

C = O(n)

0.3 Types of Linked Lists


0.3.1 Singly Linked List
A singly linked list consists of nodes where each node contains a data element
and a link (or reference) to the next node in the sequence.

0.3.2 Doubly Linked List


A doubly linked list node contains a link to both the next and the previous
nodes. This structure takes more space than a singly linked list. With the
previous node reference, deleting the last element of the linked list is O(1)
instead of O(n).

0.3.3 Circular Linked Lists


Circular Singly Linked List

In a circular singly linked list, the last node of the list contains a pointer to the
first node of the list, forming a circular loop.

Circular Doubly Linked List

A circular doubly linked list combines properties of both doubly linked lists and
circular linked lists. Each element is connected to its previous and next elements,
and the last node points back to the first node, completing the circular structure.

0.4 Singly Linked List Operations


0.4.1 isEmpty()
Checks if the linked list is empty.
1 return head == null ;
6 CONTENTS

0.4.2 AddLast(item)
Adds an item to the end of the linked list. Time complexity: O(1).
1 Node node = new Node ( item ) ;
2 if ( isEmpty () )
3 head = tail = node ;
4 else {
5 tail . next = node ;
6 tail = node ;
7 }

0.4.3 AddFirst(item)
Adds an item to the beginning of the linked list. Time complexity: O(1).
1 Node node = new Node ( item ) ;
2 if ( isEmpty () )
3 head = tail = node ;
4 else {
5 node . next = head ;
6 head = node ;
7 }

0.4.4 indexOf(item) o(n)


Finds the index of the first occurrence of an item in the linked list. Time
complexity: O(n).
1 Node current = head ;
2 int index = 0;
3 while ( current != null ) {
4 if ( current . value == item )
5 return index ;
6 current = current . next ;
7 index ++;
8 }
9 return -1;

0.4.5 contains(item) O(n)


Checks if the linked list contains a specific item.
1 return indexOf ( item ) != -1;

0.4.6 removeFirst()
Removes the first item from the linked list. Time complexity: O(1).
1 if ( isEmpty () )
2 throw new N o S u c h E l e m e n t E x c e p t i o n () ;
3 else if ( head == tail )
4 head = tail = null ;
0.4. SINGLY LINKED LIST OPERATIONS 7

5 else {
6 Node second = head . next ;
7 head . next = null ;
8 head = second ;
9 }

0.4.7 getPrevious(node)
Returns the node preceding a given node in the linked list.
1 Node current = head ;
2 while ( current != null ) {
3 if ( current . next == node )
4 return current ;
5 current = current . next ;
6 }
7 return null ;

0.4.8 removeLast()
Removes the last item from the linked list. Time complexity: O(n).
1 if ( isEmpty () )
2 throw new N o S u c h E l e m e n t E x c e p t i o n () ;
3 else if ( head == tail )
4 head = tail = null ;
5 else {
6 Node previous = getPrevious ( tail ) ;
7 previous . next = null ;
8 tail = previous ;
9 }

0.4.9 removeItem(value)
Removes the first occurrence of a specific value from the linked list. Time
complexity: O(n).
1 if ( isEmpty () )
2 throw new N o S u c h E l e m e n t E x c e p t i o n () ;
3 Node current = head ;
4 Node previous = null ;
5 while ( current != null ) {
6 if ( current . value == value )
7 break ;
8 previous = current ;
9 current = current . next ;
10 }
11 if ( current != null ) {
12 if ( previous == null )
13 removeFirst () ;
14 else {
15 Node nextItem = current . next ;
16 current . next = null ;
17 previous . next = nextItem ;
8 CONTENTS

18
19 if ( current == tail )
20 tail = prev ;
21 }
22 }

0.4.10 Reverse()

Reverses the linked list in place.

1 if ( isEmpty () )
2 return ;
3 Node previous = head ;
4 Node current = head . next ;
5 while ( current != null ) {
6 Node next = current . next ;
7 current . next = previous ;
8 previous = current ;
9 current = next ;
10 }
11 tail = head ;
12 tail . next = null ;
13 head = previous ;

0.4.11 getKthFromEnd(k)

Finds the k-th node from the end of the linked list.

1 if ( k < 1)
2 throw new I n d e x O u t O f B o u n d s E x c e p t i o n ( " Out of bounds index " ) ;
3 Node a = head ;
4 Node b = head ;
5 int index = 0;
6 while ( b != null && index < k ) {
7 b = b . next ;
8 index ++;
9 }
10 if ( index < k )
11 throw new I n d e x O u t O f B o u n d s E x c e p t i o n ( " Out of bounds index " ) ;
12 while ( b != null ) {
13 a = a . next ;
14 b = b . next ;
15 }
16 return a . value ;
0.5. ARRAYS VS LINKED LIST: 9

0.5 Arrays vs Linked List:


0.6 Stacks
0.6.1 Dynamic Representation
LIFO (Last In First Out) Principle
A dynamic stack stores objects in a vertical tower.

empty()
Checks if the stack is empty.
1 return peek == null ;

Push(value)
Pushes a value onto the stack.
1 Node newItem = new Node () ;
2 newItem . value = value ;
3 newItem . next = peekNode ;
4 peekNode = newItem ;

pop()
Pops the top value off the stack and returns it.
1 // Check if empty and throw exception if needed
2 var value = peekNode . value ;
3 var next = peekNode . next ;
4 peekNode . next = null ;
5 peekNode = next ;
6 return value ;
10 CONTENTS

peek()

Returns the value at the top of the stack without removing it.
1 // Check if empty and throw exception if needed
2 return peekNode . value ;

Check if string is balanced ((1+¡1¿ = [11])

Checks if a string of brackets is balanced.


1 private final List < Character > leftBrackets = Arrays . asList ( ’( ’ , ’{ ’
, ’[ ’ , ’ < ’) ;
2 private final List < Character > rightBrackets = Arrays . asList ( ’) ’ , ’}
’ , ’] ’ , ’ > ’) ;
3
4 boolean isBalanced ( String str ) {
5 Stack < Character > stack = new Stack < >() ;
6 for ( char ch : str . toCharArray () ) {
7 if ( isLeftBracket ( ch ) ) {
8 stack . push ( ch ) ;
9 } else if ( is RightBr acket ( ch ) ) {
10 if ( stack . empty () ) {
11 return false ;
12 }
13 char top = stack . peek () ;
14 if (! matchBrackets ( top , ch ) ) {
15 return false ;
16 }
17 stack . pop () ;
18 }
19 }
20 return stack . empty () ;
21 }
22
23 boolean isR ightBrac ket ( char ch ) {
24 return rightBrackets . contains ( ch ) ;
25 }
26
27 boolean isLeftBracket ( char ch ) {
28 return leftBrackets . contains ( ch ) ;
29 }
30
31 boolean matchBrackets ( char left , char right ) {
32 return leftBrackets . indexOf ( left ) == rightBrackets . indexOf (
right ) ;
33 }

0.6.2 Array Representation


LIFO (Last In First Out) Principle

An array-backed stack representation.


0.7. QUEUE 11

Implementation

1 class Stack {
2 private int [] items ;
3 private int top ;
4 private int capacity ;
5
6 public Stack ( int capacity ) {
7 this . capacity = capacity ;
8 this . items = new int [ capacity ];
9 this . top = -1; // Initialize top index to -1 ( empty stack )
10 }
11
12 public boolean isEmpty () {
13 return top == -1;
14 }
15
16 public void push ( int value ) {
17 if ( top == capacity - 1) {
18 // Handle stack overflow ( expand array or throw
exception )
19 System . out . println ( " Stack overflow " ) ;
20 return ;
21 }
22 items [++ top ] = value ;
23 }
24
25 public int pop () {
26 if ( isEmpty () ) {
27 // Handle stack underflow ( throw exception or return
error value )
28 System . out . println ( " Stack underflow " ) ;
29 return -1;
30 }
31 return items [ top - -];
32 }
33
34 public int peek () {
35 if ( isEmpty () ) {
36 // Handle empty stack ( throw exception or return error
value )
37 System . out . println ( " Stack is empty " ) ;
38 return -1;
39 }
40 return items [ top ];
41 }
42 }

0.7 Queue
A Queue is a FIFO (First In First Out) data structure. We use it when we want
to share a resource amoungst many consumers
12 CONTENTS

0.7.1 Array Representation


Definition
We use circular arrays to implement the Queue.
1 int [] queue ;
2 int head ;
3 int tail ;
4 int count ;
5
6 public ArrayQueue ( int size )
7 {
8 queue = new int [ size ];
9 head = 0;
10 tail = 0;
11 count = 0;
12 }

enqueue
Adds an element to the end of the queue.
1 public void enqueue ( int value )
2 {
3 if ( isFull () )
4 throw new Exception ( " Queue is full " ) ;
5
6 queue [ tail ] = value ;
7 tail = ( tail + 1) % queue . length ;
8 count ++;
9 }

dequeue
Removes and returns the element at the front of the queue.
1 public int dequeue ()
2 {
3 if ( isEmpty () )
4 throw new Exception ( " Queue is empty " ) ;
5
6 int value = queue [ head ];
7 head = ( head + 1) % queue . length ;
8 count - -;
9 return value ;
10 }

isEmpty
Checks if the queue is empty.
1 public boolean isEmpty ()
2 {
3 return count == 0;
4 }
0.7. QUEUE 13

isFull
Checks if the queue is full.
1 public boolean isFull ()
2 {
3 return count == queue . length ;
4 }

0.7.2 Implementation with stack


To implement a queue using two stacks, we need two stacks: stack1 and stack2.
1 public class StackQueue {
2
3 private Stack < Integer > s1 ;
4 private Stack < Integer > s2 ;
5
6 public StackQueue ()
7 {
8 s1 = new Stack < >() ;
9 s2 = new Stack < >() ;
10 }
11 }

The queue operations are defined as follows:

Enqueue Operation O(1)


To add an element to the queue, push the element onto stack1.

• Push the element onto stack1.

1 public void enqueue ( int value )


2 {
3 stack1 . push ( value ) ;
4 }

Dequeue Operation O(n)


To remove an element from the queue:

• If both stack1 and stack2 are empty, the queue is empty (underflow
condition).

• If stack2 is empty, transfer all elements from stack1 to stack2. This


step reverses the order of elements.

• Pop the top element from stack2.


14 CONTENTS

1 public int dequeue ()


2 {
3 if ( isEmpty () )
4 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
5
6 moveS1toS2 () ;
7
8 return stack2 . pop () ;
9 }
10
11 private void moveS1toS2 () {
12 if ( stack2 . empty () )
13 while (! stack1 . empty () )
14 stack2 . push ( stack1 . pop () ) ;
15 }

Is Empty Operation O(1)


To check if the queue is empty:
• Return True if both stack1 and stack2 are empty.
• Return False otherwise.

1 public boolean isEmpty ()


2 {
3 return stack1 . empty () && stack2 . empty () ;
4 }

Peek Operation O(1)


To get the front element of the queue without removing it:
• If stack2 is empty, transfer all elements from stack1 to stack2.
• Return the top element from stack2.

1 public int peek ()


2 {
3 if ( isEmpty () )
4 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
5
6 moveS1toS2 () ;
7
8 return stack2 . peek () ;
9 }

0.8 Priority qeueu


An array-based priority queue is a data structure that allows for the storage
of elements with associated priorities, where the highest (or lowest) priority
element can be quickly accessed.
0.8. PRIORITY QEUEU 15

0.8.1 Array representatuion


1 class PriorityQueue
2 {
3 int [] array ;
4 int count ;
5
6 public PriorityQueue ( int capacity )
7 {
8 array = new int [ capacity ];
9 }
10 }

isFull O(1)

1 public boolean isFull ()


2 {
3 return count = thsi . array . lenght ;
4 }

add O(n)

1 public void add ( int value )


2 {
3 if ( isFull )
4 throw new Exception ( " the queue is full " )
5
6 var i = s h i f t I t e m s T o I n s e r t ( value ) ;
7
8 this . array [ i ] = value ;
9
10 count ++;
11 }
12
13 private int s h i f t I t e m s T o I n s e r t ( value )
14 {
15 int i ;
16 for ( i = count -1; i >=0 ;i - -)
17 {
18 if ( value < this . array [ i ])
19 thsi . array [ i +1] = thsi . array [ i ]
20 else
21 break ;
22 }
23
24 return i +1;
25 }

isEmpty O(1)

1 public boolean isEmpty ()


2 {
16 CONTENTS

3 return count == 0;
4 }

remove O(1)

1 public int remove ()


2 {
3 if ( isEmpty () )
4 throw new Exception ( " the queue is empty " )
5
6 return this . array [ - - count ];
7 }

0.9 Hash tables (Dictionaries)


a hash table is a data structure often used to implement the map (a.k.a. dictio-
nary or associative array) abstract data type. A hash table uses a hash function
to compute an index, also called a hash code, into an array of buckets or slots,
from which the desired value can be found. During lookup, the key is hashed
and the resulting hash indicates where the corresponding value is stored.

0.9.1 Hash tables operations


• Add entry with existing key : value will overwrite.

• we can add null keys and values to hash tables.

• hash map function containsKey will run in O(1) time complexity.

• hash map function containValue will run in O(n time complexity.

First no repeated char

1 public char f i n d F i r s t N o R e p e a t e d C h a r ( String s )


2 {
3 Map < Character , Integer > map = new HashMap () ;
4
5 var chars = s . toCharArray () ;
6
7 for ( var ch : chars )
8 {
9 int count = map . containsKey ( ch ) ? map . get ( ch ) : 0;
10 map . put (c , count + 1) ;
11 }
12
13 for ( var ch : chars )
14 {
15 if ( map . get ( ch ) == 1)
16 return ch ;
17 }
0.10. SETS 17

18
19 return Character . MIN_VALUE ;
20 }

0.10 Sets
a set is an abstract data type that can store unique values, without any partic-
ular order. It is a computer implementation of the mathematical concept of a
finite set

0.10.1 Sets operations


First repeated character

1 public char f i n d F i r s t R e p e a t e d C h a r ( String s )


2 {
3 Set < Integer > set = new HashSet () ;
4
5 for ( var ch : s )
6 {
7 if ( set . contains ( ch ) )
8 return ch ;
9
10 set . add ( ch ) ;
11 }
12
13 return Character . MIN_VALUE ;
14 }
18 CONTENTS
Chapter 1

Non-linear data structure

Recursion

1 Public void factorial ( int n )


2 {
3 // Base condition
4 If ( n == 0)
5 Return 1;
6 Else
7 Return n * factorial (n -1) ;
8 }

1.1 Trees

Every element of tree called Node


The first node is called Root
The nodes without children are called Leafs

19
20 CHAPTER 1. NON-LINEAR DATA STRUCTURE

1.2 Binary tree


1.2.1 Traversal tree

preorder traversal:

1 public void t r a v e r s a l P r e O r d e r ( Node root )


2 {
3 if ( root == null )
4 return ;
5
6 System . out . println ( root . value ) ;
7 t r a v e r s a l P r e O r d e r ( root . leftChild )
8 t r a v e r s a l P r e O r d e r ( root . rightChild ) ;
9 }

Inorder traversal:

1 public void t r a v e r s a l I n O r d e r ( Node root )


2 {
3 if ( root == null )
4 return ;
5
6 t r a v e r s a l P r e O r d e r ( root . leftChild )
7 System . out . println ( root . value ) ;
8 t r a v e r s a l P r e O r d e r ( root . rightChild ) ;
9 }
1.2. BINARY TREE 21

Postorder traversal:

1 public void t r a v e r s a l P o s t O r d e r ( Node root )


2 {
3 if ( root == null )
4 return ;
5
6 t r a v e r s a l P r e O r d e r ( root . leftChild )
7 t r a v e r s a l P r e O r d e r ( root . rightChild ) ;
8 System . out . println ( root . value ) ;
9 }

Level order traversal

1 public void l e v e l O r d e r T r a v e r s a l ()
2 {
3 for ( int i =0; i <= height () ; i ++)
4 {
5 ArrayList < Integer > list = n od eA t KD is ta n ce ( i ) ;
6 for ( int v : list )
7 {
8 System . out . println ( v ) ;
9 }
10 }
11 }
22 CHAPTER 1. NON-LINEAR DATA STRUCTURE

1.2.2 Height and depth of tree node

Height of binary tree:

1 private int height ( TreeNode root )


2 {
3 if ( root == null )
4 return -1;
5
6 if ( root . leftChild == null && root . rightChild == null )
7 return 0;
8
9 return 1 + Math . max ( height ( root . leftChild ) , height ( root .
rightChild ) ) ;
10 }

1.2.3 Minimum O(n)


1 private int minimum ( TreeNode root )
2 {
3 if ( root == null )
4 return Integer . MAX_VALUE ;
5
6 if ( root . leftChild == null && root . rightChild == null )
7 return root . value ;
8
9 var left = minimum ( root . leftChild ) ;
10 var right = minimum ( root . rightChild ) ;
11
1.3. BINARY SEARCH TREE 23

12 return Math . min ( Math . min ( left , right ) , root . value ) ;


13 }

1.2.4 Equality
1 public boolean equal ( TreeNode node1 , TreeNode node2 )
2 {
3 if ( node1 == null && node2 == null )
4 return true ;
5
6 if ( node1 == null || node2 == null )
7 return false ;
8
9 boolean left = equal ( node1 . leftChild , node2 . leftChild ) ;
10 boolean right = equal ( node1 . rightChild , node2 . rightChild ) ;
11
12 return node1 . value == node2 . value && left && right ;
13
14 }

1.2.5 Get nodes at k distance


1 public ArrayList no d eA tK Di s ta nc e ( int k )
2 {
3 var list = new ArrayList < Integer >() ;
4 n od eA tK D is ta nc e ( root ,k , list ) ;
5 return list ;
6 }
7
8 private void n od eA t KD is ta n ce ( TreeNode node , int k , ArrayList <
Integer > list )
9 {
10 if ( node == null && k >0)
11 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
12
13 if ( k ==0)
14 {
15 list . add ( node . value ) ;
16 return ;
17 }
18
19
20 n od eA tK D is ta nc e ( node . leftChild , k -1 , list ) ;
21 n od eA tK D is ta nc e ( node . rightChild , k -1 , list ) ;
22
23 }

1.3 Binary search tree


left ¡ node ¡ right
all nodes in the left are smaller than node, all nodes in the right are greater
than node
24 CHAPTER 1. NON-LINEAR DATA STRUCTURE

1.3.1 complexity of operations


IF tree balanced:

• Lookup : O(log(n))

• Insert : O(log(n))

• Delete : O(log(n))

Else (worst scenario): O(n)

1.3.2 Operations
Insert:

1 public void insert ( int value )


2 {
3 var newNode = new TreeNode () ;
4 newNode . value = value ;
5
6 if ( root == null )
7 root = newNode ;
8 else
9 {
10 var currentNode = root ;
11 TreeNode previous = null ;
12
13 while ( currentNode != null )
14 {
15 previous = currentNode ;
16
17 if ( currentNode . value > value )
18 currentNode = currentNode . leftChild ;
19 else
20 currentNode = currentNode . rightChild ;
21
22 }
23
24 if ( previous . value > value )
25 previous . leftChild = newNode ;
26 else
27 previous . rightChild = newNode ;
28 }
29
30 }

recursive insert

1 public void insert ( int value )


2 {
3 root = insert ( root , value ) ;
4
5 }
1.3. BINARY SEARCH TREE 25

6
7 private AVLNode insert ( AVLNode node , int value )
8 {
9 if ( node == null )
10 return new AVLNode ( value ) ;
11
12 if ( node . value > value )
13 node . leftChild = insert ( node . leftChild , value ) ;
14 else
15 node . rightChild = insert ( node . rightChild , value ) ;
16
17 return node ;
18
19 }

find:

1 public boolean find ( int value )


2 {
3 var current = root ;
4 while ( current != null )
5 {
6 if ( current . value == value )
7 return true ;
8
9 else if ( current . value > value )
10 current = current . leftChild ;
11
12 else
13 current = current . rightChild ;
14 }
15
16 return false ;
17 }

Min of binary search tree O(log(n)):

1 private int minimum ( TreeNode root )


2 {
3 if ( root . leftChild == null && root . rightChild == null )
4 return root . value ;
5
6 return minimum ( root . leftChild ) ;
7 }

1.3.3 Check if the tree is binary search tree


1 boolean structured ( TreeNode node , int max , int min )
2 {
3 if ( node == null )
4 return true ;
5
26 CHAPTER 1. NON-LINEAR DATA STRUCTURE

6 if ( node . value <= min || node . value >= max )


7 return false ;
8
9 boolean left = structured ( node . leftChild , node . value , min ) ;
10 boolean right = structured ( node . rightChild , max , node . value
);
11
12 return left && right ;
13
14 }

1.4 AVL Tree


1.4.1 Balance Factor
BF = height(lef t) − height(right)
BF > 1 ⇒ node left heavy
BF < −1 ⇒ node right heavy

1.4.2 Insert
1 public void insert ( int value )
2 {
3 root = insert ( root , value ) ;
4
5 }
6
7 private AVLNode insert ( AVLNode node , int value )
8 {
9 if ( node == null )
10 return new AVLNode ( value ) ;
11
12 if ( node . value > value )
13 node . leftChild = insert ( node . leftChild , value ) ;
14
15 else
16 node . rightChild = insert ( node . rightChild , value ) ;
17
18 setHeight ( node ) ;
19
20 node = balance ( node ) ;
21
22 return node ;
23
24 }
25
26 AVLNode balance ( AVLNode node )
27 {
28 int bf = balanceFactor ( node ) ;
29 if ( bf > 1)
30 {
1.4. AVL TREE 27

31 if ( balanceFactor ( node . leftChild ) <0)


32 node . leftChild = leftRotate ( node . leftChild ) ;
33
34 return rightRotate ( node ) ;
35
36 }
37 else if ( bf < -1)
38 {
39 if ( balanceFactor ( node . rightChild ) >0)
40 node . rightChild = rightRotate ( node . rightChild ) ;
41
42 return leftRotate ( node ) ;
43
44 }
45
46 return node ;
47 }
48
49 private AVLNode leftRotate ( AVLNode node )
50 {
51 var newRoot = node . rightChild ;
52
53 node . rightChild = newRoot . leftChild ;
54 newRoot . leftChild = node ;
55
56 setHeight ( node ) ;
57 setHeight ( newRoot ) ;
58
59 return newRoot ;
60 }
61
62 private AVLNode rightRotate ( AVLNode node )
63 {
64 var newRoot = node . leftChild ;
65
66 node . leftChild = newRoot . rightChild ;
67 newRoot . rightChild = node ;
68
69 setHeight ( node ) ;
70 setHeight ( newRoot ) ;
71
72 return newRoot ;
73 }
74
75 private void setHeight ( AVLNode node )
76 {
77 node . height = Math . max ( getHeight ( node . leftChild ) , getHeight
( node . rightChild ) ) +1;
78 }
79
80 private int balanceFactor ( AVLNode node )
81 {
82 if ( node == null )
83 return 0;
84
85 return getHeight ( node . leftChild ) - getHeight ( node .
rightChild ) ;
28 CHAPTER 1. NON-LINEAR DATA STRUCTURE

86 }
87
88 private int getHeight ( AVLNode node )
89 {
90 if ( node == null )
91 return -1;
92 else
93 return node . height ;
94 }

1.5 Heap
Heap is particular type of tree, witch is:

• Complete: means every level of tree must be filled except from the left
(so we can have only left leafs in the tree)

• satisfies heap property: means that every node in a level is:

– greater or equal the previous level : Min Heap


– less or equal the previous level : Max Heap

1.5.1 Heap representation


we can simply represent it with an array because the heap is complete (so there
will be no gaps in the array) where:

• Index of left child = 2i + 1

• Index of right child = 2i + 2

• parent = int((i − 1)/2)

1.5.2 Operations
Insert:

1 private boolean isFull ()


2 {
3 return size >= heap . length ;
4 }
5
6 private int parent ( int i )
7 {
8 return (i -1) /2;
9 }
10
11 private void swap ( int first , int seconde )
12 {
13 var temp = heap [ first ];
1.5. HEAP 29

14 heap [ first ] = heap [ seconde ];


15 heap [ seconde ] = temp ;
16 }
17
18 private void bubbleUp ()
19 {
20 int i = size -1;
21 var p = parent ( i ) ;
22 while (p >=0 && heap [ p ] < heap [ i ])
23 {
24 swap (i , p ) ;
25 i=p;
26 p = parent ( i ) ;
27 }
28 }
29
30 public void insert ( int value )
31 {
32 if ( isFull () )
33 throw new I l l e g a l S t a t e E x c e p t i o n () ;
34
35 heap [ size ++]= value ;
36
37 bubbleUp () ;
38 }

remove:

1 public boolean isEmpty ()


2 {
3 return size ==0;
4 }
5
6 private int l eftChild Index ( int index )
7 {
8 return 2 * index + 1;
9 }
10
11 private int ri g ht Ch il d In de x ( int index )
12 {
13 return 2 * index + 2;
14 }
15
16 private int leftChild ( int index )
17 {
18 return heap [ leftC hildInde x ( index ) ];
19 }
20
21 private int rightChild ( int index )
22 {
23 return heap [ r i gh tC hi l dI nd ex ( index ) ];
24 }
25
26 private boolean hasLeftChild ( int index )
27 {
28 return leftCh ildInde x ( index ) < size ;
30 CHAPTER 1. NON-LINEAR DATA STRUCTURE

29 }
30
31 private boolean hasRightChild ( int index )
32 {
33 return r ig h tC hi ld I nd ex ( index ) < size ;
34 }
35
36
37 private boolean isValid ( int index )
38 {
39 if (! hasLeftChild ( index ) )
40 return true ;
41
42 if (! hasRightChild ( index ) )
43 return heap [ index ] > leftChild ( index ) ;
44
45 return heap [ index ] > leftChild ( index ) && heap [ index ] >
rightChild ( index ) ;
46 }
47
48 private int g r e a t e s t C h i l d I n d e x ( int index )
49 {
50 if (! hasLeftChild ( index ) )
51 return r ig h tC hi l dI nd ex ( index ) ;
52
53 if (! hasRightChild ( index ) )
54 return leftC hildInde x ( index ) ;
55
56 return leftChild ( index ) > rightChild ( index ) ? leftC hildInde x (
index ) : ri gh t Ch il dI n de x ( index ) ;
57 }
58
59 private void bubbleDown ()
60 {
61 int i =0;
62
63 while (i < size && ! isValid ( i ) )
64 {
65
66 int gci = g r e a t e s t C h i l d I n d e x ( i ) ;
67 swap (i , gci ) ;
68 i = gci ;
69 }
70 }
71
72 public int remove ()
73 {
74 if ( isEmpty () )
75 throw new I l l e g a l S t a t e E x c e p t i o n () ;
76
77 int root = heap [0];
78 heap [0]= heap [ - - size ];
79
80 bubbleDown () ;
81
82 return root ;
83
1.5. HEAP 31

84 }

Heapify:

1 public void heapify ( int [] a )


2 {
3 for ( int i = a . length /2 -1; i >=0; i - -)
4 {
5 heapify (a , i ) ;
6 }
7
8 }
9
10 private void heapify ( int [] a , int i )
11 {
12 int maxIndex = i ;
13
14
15 int leftChi ldIndex = 2* i +1;
16 if ( leftChildIndex < a . length && a [ leftCh ildInde x ] > a [ maxIndex ]
)
17 maxIndex = leftChi ldIndex ;
18
19 int r ig ht C hi ld In d ex = 2* i +2;
20 if ( rightChildIndex < a . length && a [ r i gh tC h il dI nd e x ] > a [
maxIndex ] )
21 maxIndex = r ig ht C hi ld In d ex ;
22
23 if ( maxIndex != i )
24 {
25 int temp = a [ i ];
26 a [ i ] = a [ maxIndex ];
27 a [ maxIndex ] = temp ;
28
29 heapify (a , maxIndex ) ;
30 }
31 }

1.5.3 Sort values with ”SortHeap”


We must just create a heap using our values (let’s be Max heap like the code
above demonstrate), then we must loop and remove root value from heap (the
max values) and that give us descending order sorting, to sort in ascending order
(with Max Heap) we loop in reverse order.
1 int main ()
2 {
3 Heap h = new Heap (100) ;
4
5 int [] a = {5 ,4 ,2 ,10 ,9 ,8 ,7 ,0};
6
7 for ( int v : a )
8 {
9 h . insert ( v ) ;
32 CHAPTER 1. NON-LINEAR DATA STRUCTURE

10 }
11
12 for ( int i = a . length -1; i >=0; i - -)
13 a [ i ] = h . remove () ;
14
15 System . out . println ( Arrays . toString ( a ) ) ;
16 }

1.5.4 Priority queue with heap


we can simply use heap (maxheap) for priority queue.

priority queue : Insert( O(n) ) — delete( O(1) )


priority queue with heap : Insert( O(log n) ) — delete( O(log n))
1 public class P r i o r i t y Q u e u e u W i t h H e a p
2 {
3 private Heap heap = new Heap (100) ;
4
5 public void enqueue ( int item )
6 {
7 heap . insert ( item ) ;
8 }
9
10 public int dequeue ()
11 {
12 return heap . remove () ;
13 }
14
15 public boolean isEmpty ()
16 {
17 return heap . isEmpty () ;
18 }
19 }

1.5.5 Find k largest value


1 int kLargest ( int [] array , int k )
2 {
3 if (k <1)
4 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
5
6 Heap h = new Heap (100) ;
7 for ( int i =0; i < array . length ; i ++)
8 h . insert ( array [ i ]) ;
9
10 for ( int i =0; i <k -1; i ++)
11 h . remove () ;
12
13 return h . remove () ;
14
15 }
1.6. GRAPHS 33

1.6 Graphs
Each element of graph is called Vertex, and each connection between two ver-
tices is called edge.

We call a vertex adjacent to another vertex if it is directly connected to it.

We use weights to vertices (edges) to see how strong the connection is be-
tween them.

There are two types of graphs:

• Directed graph

• Non directed graph

1.6.1 Implementation of graph in code


There are two ways to implement graph in code:

Adjacency matrix:
In graph theory and computer science, an adjacency matrix is a square matrix
used to represent a finite graph. The elements of the matrix indicate whether
pairs of vertices are adjacent or not in the graph.

• space complexity of this approach: O(n2 )

• Add a new node: if the matrix is full we must allocate a new matrix
with new size and copy the old matrix to it so O(V 2 )

• Remove a node: we need to allocate a smaller matrix so O((n−1)2 ) ==


O(n2 )

• Add edge / Remove edge / check if two vertices are adjacent:


O(1)

• finding neighbors of vertex: O(V)

Adjacency list:
In graph theory and computer science, an adjacency list is a collection of un-
ordered lists used to represent a finite graph. Each unordered list within an
adjacency list describes the set of neighbors of a particular vertex in the graph.

• space complexity of this approach: O(V + E) (E is totale number of


edges) (in worst case (dense graph) O(V 2 )

• Add node: O(1)


34 CHAPTER 1. NON-LINEAR DATA STRUCTURE

• remove a node: here we must remove the node so O(V) and remove
it from every edge of other nodes so in worst case (dense graph): O((V-
1)*V)== O(V 2 ) so the totale is O(V + V 2 ) == O(V 2 )

• add an edge: O(K), k is number of edges of the vertex, we need to iterate


the list to see if the edge is already exists, O(V) in worst case.

• remove an edge: iterate t5he list to find previous and delete it, O(K),
O(V) in worst case.

• check if two vertices are adjacent: O(K), O(V) in worst case.

• finding neighbors of vertex: O(K), O(V) in worst case.

What we use:
So in general we use adjacency matrix for dense graph, otherwise we use adja-
cency list.

1.6.2 Graph operations


1.6. GRAPHS 35

1 public class Graph {


2
3
4
5 Map < String , List < String > > adjancan cyList ;
6
7 public Graph ()
8 {
9 this . ad jancancy List = new HashMap < String , List < String > >() ;
10
11 }
12
13 public void addNode ( String label )
14 {
15 this . ad jancancy List . putIfAbsent ( label , new ArrayList < String
>() ) ;
16 }
17
18
19
20 public void addEdge ( String from , String to )
21 {
22 if ( this . adja ncancyL ist . get ( from ) == null )
23 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
24
25 if ( this . adja ncancyL ist . get ( to ) == null )
26 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
27
28 this . ad jancancy List . get ( from ) . add ( to ) ;
29 }
30
31 public void removeNode ( String label )
32 {
33 var node = adjanc ancyList . get ( label ) ;
34 if ( node == null )
35 return ;
36
37 for ( String key : adjan cancyLi st . keySet () )
38 {
39 adja ncancyLi st . get ( key ) . remove ( label ) ;
40 }
41
42 adja ncancyLi st . remove ( label ) ;
43 }
44
45 public void removeEdge ( String from , String to )
46 {
47 var fromNode = adjancan cyList . get ( from ) ;
48 var toNode = adj ancancyL ist . get ( to ) ;
49
50 if ( fromNode == null || toNode == null )
51 return ;
52
53 adja ncancyLi st . get ( from ) . remove ( to ) ;
54
55 }
56
36 CHAPTER 1. NON-LINEAR DATA STRUCTURE

57 public void print ()


58 {
59 for ( String s : this . adj ancancyL ist . keySet () )
60 {
61 System . out . println ( s + " is connected to " +
adja ncancyLi st . get ( s ) . toString () ) ;
62 }
63 }
64 }

1.6.3 Graph depth first traversal


Recursive method:

1 public void d e p t h F i r s t T r a v e r s a l ( String root )


2 {
3 var node = adjanc ancyList . get ( root ) ;
4 if ( node == null )
5 return ;
6
7 Set < String > visited = new HashSet < >() ;
8 d e p t h F i r s t T r a v e r s a l ( root , visited ) ;
9 }
10
11 private void d e p t h F i r s t T r a v e r s a l ( String label , Set < String >
visited )
12 {
13
14 System . out . println ( label ) ;
15 visited . add ( label ) ;
16
17 for ( String v : adja ncancyL ist . get ( label ) )
18 if (! visited . contains ( label ) )
19 d e p t h F i r s t T r a v e r s a l (v , visited ) ;
20
21 }

Iterative method:

1 public void d e p t h F i r s t T r a v e r s a l I t e r a t i v e ( String root )


2 {
3 var node = adjanc ancyList . get ( root ) ;
4 if ( node == null )
5 return ;
6
7 Set < String > visited = new HashSet < >() ;
8
9 Stack < String > s = new Stack < >() ;
10 s . push ( root ) ;
11
12 while (! s . empty () )
13 {
14 String current = s . pop () ;
15
1.6. GRAPHS 37

16 if ( visited . contains ( current ) )


17 continue ;
18
19 System . out . println ( current ) ;
20 visited . add ( current ) ;
21
22 for ( String v : adjancan cyList . get ( current ) )
23 {
24 if (! visited . contains ( v ) )
25 s . push ( v ) ;
26 }
27 }
28 }

1.6.4 Level order traversal


1 public void l e v e l O r d e r T r a v e r s a l ( String root )
2 {
3 var node = adjanc ancyList . get ( root ) ;
4 if ( node == null )
5 return ;
6
7 Queue < String > q = new ArrayDeque < >() ;
8 Set < String > visited = new HashSet < >() ;
9 q . add ( root ) ;
10
11 while (! q . isEmpty () )
12 {
13 var current = q . poll () ;
14
15 if ( visited . contains ( current ) )
16 continue ;
17
18 System . out . println ( current ) ;
19 visited . add ( current ) ;
20
21 for ( String v : adjancan cyList . get ( current ) )
22 {
23 if (! visited . contains ( v ) )
24 q . add ( v ) ;
25 }
26 }
27 }

1.6.5 Topological sorting


In computer science, a topological sort or topological ordering of a directed
graph is a linear ordering of its vertices such that for every directed edge from
vertex u to vertex v, u comes before v in the ordering
1 public List < String > t o p o l o g i c a l S o r t i n g ( String root )
2 {
3 if ( adjancecyList . get ( root ) == null )
4 return null ;
38 CHAPTER 1. NON-LINEAR DATA STRUCTURE

5
6 Stack < String > s = new Stack < String >() ;
7 Set < String > visited = new HashSet < >() ;
8
9 for ( String v : adjancecyList . keySet () )
10 t o p o l o g i c a l S o r t i n g (v , visited , s ) ;
11
12 List < String > sorted = new ArrayList < >() ;
13
14 while (! s . empty () )
15 sorted . add ( s . pop () ) ;
16
17 return sorted ;
18 }
19
20 private void t o p o l o g i c a l S o r t i n g ( String node , Set < String >
visited , Stack < String > s )
21 {
22 if ( visited . contains ( node ) )
23 return ;
24
25 visited . add ( node ) ;
26
27 for ( var n : adjancecyList . get ( node ) )
28 {
29 t o p o l o g i c a l S o r t i n g (n , visited , s ) ;
30 }
31
32 s . push ( node ) ;
33
34 }

1.6.6 Detect cycle


1 public boolean hasCycle ()
2 {
3
4 Set < String > all = new HashSet < >( adjancecyList . keySet () ) ;
5 Set < String > visiting = new HashSet < >() ;
6 Set < String > visited = new HashSet < >() ;
7
8 while (! all . isEmpty () )
9 {
10 var current = all . iterator () . next () ;
11
12 if ( hasCycle ( current , all , visiting , visited ) )
13 return true ;
14 }
15
16 return false ;
17 }
18
19 private boolean hasCycle ( String node , Set < String > all , Set <
String > visiting , Set < String > visited )
20 {
21 all . remove ( node ) ;
1.7. WEIGHTED AND NON DIRECTED GRAPH 39

22 visiting . add ( node ) ;


23
24 for ( var n : adjancecyList . get ( node ) )
25 {
26 if ( visited . contains ( n ) )
27 continue ;
28
29 if ( visiting . contains ( n ) )
30 return true ;
31
32 if ( hasCycle (n , all , visiting , visited ) )
33 return true ;
34
35 }
36
37 visited . add ( node ) ;
38 visiting . remove ( node ) ;
39
40 return false ;
41 }

1.7 Weighted and non directed graph


1.7.1 Implementation
1 public class WeightedGraph {
2
3 private class Edge
4 {
5 String from ;
6 String to ;
7 int weight ;
8
9 public Edge ( String from , String to , int weight )
10 {
11 this . from = from ;
12 this . to = to ;
13 this . weight = weight ;
14 }
15
16 public String toString ()
17 {
18 return from + " -( " + weight + " ) ->" + to ;
19 }
20 }
21
22 Map < String , List < Edge > > adjancecyList ;
23
24 public WeightedGraph ()
25 {
26 adjancecyList = new HashMap < >() ;
27 }
28
29 public void addNode ( String node )
30 {
40 CHAPTER 1. NON-LINEAR DATA STRUCTURE

31 adjancecyList . putIfAbsent ( node , new ArrayList < >() ) ;


32 }
33
34 public void addEdge ( String from , String to , int weight )
35 {
36 if ( adjancecyList . get ( from ) == null || adjancecyList . get ( to ) ==
null )
37 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
38
39 adjancecyList . get ( from ) . add (
40 new Edge ( from , to , weight )
41 );
42
43 adjancecyList . get ( to ) . add (
44 new Edge ( to , from , weight )
45 );
46 }
47
48 public void print ()
49 {
50 for ( String n : adjancecyList . keySet () )
51 {
52 System . out . println ( n + " is connected to " + Arrays .
toString ( adjancecyList . get ( n ) . toArray () ) ) ;
53 }
54 }
55
56 }

1.7.2 Detect cycle


1 public boolean hasCycle ()
2 {
3 Set < String > visited = new HashSet < >() ;
4
5 for ( var v : adjancecyList . keySet () )
6 {
7
8 if (! visited . contains ( v ) && hasCycle (v , null , visited ) )
9 return true ;
10 }
11
12 return false ;
13 }
14
15 private boolean hasCycle ( String node , String parent , Set < String
> visited )
16 {
17 if ( visited . contains ( node ) )
18 return true ;
19
20 visited . add ( node ) ;
21
22 for ( var edge : adjancecyList . get ( node ) )
23 {
24 if ( edge . to != parent )
1.8. GRAPH SHORTEST PATH 41

25 if ( hasCycle ( edge . to , node , visited ) )


26 return true ;
27 }
28
29 return false ;
30 }

1.8 graph shortest path


1 private class Dst
2 {
3 public int distance ;
4 public String node ;
5
6 public Dst ( String node , int distance )
7 {
8 this . node = node ;
9 this . distance = distance ;
10 }
11 }
12
13
14 public List < String > shortestPath ( String from , String to )
15 {
16 if ( adjancecyList . get ( from ) == null || adjancecyList . get ( to ) ==
null )
17 throw new I l l e g a l A r g u m e n t E x c e p t i o n () ;
18
19 Map < String , Integer > distance = new HashMap < >() ;
20 Map < String , String > previous = new HashMap < >() ;
21
22 for ( var v : adjancecyList . keySet () )
23 {
24 if ( v == from )
25 distance . put ( from , 0) ;
26 else
27 distance . put (v , Integer . MAX_VALUE ) ;
28 }
29
30 Set < String > visited = new HashSet < >() ;
31 PriorityQueue < Dst > q = new PriorityQueue < >( Comparator .
comparingInt (x - > x . distance ) ) ;
32
33 q . add ( new Dst ( from , 0) ) ;
34
35 while (! q . isEmpty () )
36 {
37 var current = q . remove () ;
38
39 visited . add ( current . node ) ;
40
41 for ( var edge : adjancecyList . get ( current . node ) )
42 {
43 if (! visited . contains ( edge . to ) )
44 {
42 CHAPTER 1. NON-LINEAR DATA STRUCTURE

45 int newDistance = distance . get ( current . node ) +


edge . weight ;
46 if ( distance . get ( edge . to ) > newDistance )
47 {
48 distance . replace ( edge . to , newDistance ) ;
49 previous . replace ( edge . to , current . node ) ;
50 }
51
52 q . add ( new Dst ( edge . to , distance . get ( edge . to ) ) ) ;
53
54
55 }
56 }
57 }
58
59
60
61 return buildPath ( previous , to ) ;
62
63 }
64
65 private List < String > buildPath ( Map < String , String > previous ,
String to )
66 {
67 Stack < String > s = new Stack () ;
68
69 s . push ( to ) ;
70 var prv = previous . get ( to ) ;
71 while ( prv != null )
72 {
73 s . push ( prv ) ;
74 prv = previous . get ( prv ) ;
75 }
76
77 List < String > l = new ArrayList < >() ;
78
79 while (! s . empty () )
80 {
81 l . add ( s . pop () ) ;
82 }
83
84 return l ;
85 }

You might also like