Exam Flashcards

1
Q

Negatives of adjacency lists

A

Enumerating over nodes directly is o(n) where n is number of vertices
if each node has k edges on average enumerating edges requires o(n*k) which equals o(m) where m is the total number of edges which scales badly

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

What is extendible hashing

A

A dynamic hashing technique where the hash code is treated as a bit string and the hash code splits when buckets overflow using more bits to differentiate keys

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Advantages and disadvantages of quadratic probing

A

Advantages: reduces clustering in comparison to linear probing
better distribution of keys in tables

disadvantages: more complex than linear probing and can still fail to resolve collision if table size isn’t a prime number
suffer from secondary clustering where keys with the same initial hash code follow the same sequence

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Psuedocode for bfs

A

BFS(Graph graph, startNode) {
currentLevel = [startNode] // Start with the list containing the start node
while currentLevel is not empty {
nextLevel = [] // Prepare a new list for the next level of nodes
for each node in currentLevel {
visit(node) // Process or visit the node
for each edge connected to node { // Explore all edges incident on the node
if edge is unexplored { // Check if the edge has been explored
neighborNode = graph.opposite(edge, node) // Find the other endpoint of the edge
if neighborNode is undiscovered { // If the neighbor node hasn’t been discovered yet
label(edge, “discovery”) // Label the edge as a discovery edge
add neighborNode to nextLevel // Add the undiscovered neighbor node to the next level
} else {
label(edge, “cross”) // If the neighbor node has already been discovered, label the edge as a cross edge
}
}
}
}
currentLevel = nextLevel // Move to the next level, update ‘currentLevel’ with the new list of nodes
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Advantages of adjacency matrices and disadvantages

A

Fast edge lookup simple query A[i][j] which is o(1)
disadvantages: requires o(n^2) memory for n nodes even if a graph is sparse
finding all neighbours is an o(n) operation as it involves scanning entire row/column

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

What’s the length of a path

A

The number of edges it traverses

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Why does dijkstras algorithm never work with negative weight

A

the algorithm assumes that adding an edge to a path will never shorten it. Negative weights violate this leading to incorrect results

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Advantages and disadvantages of extendible hashing

A

Advantages: don’t need to resize entire table, dynamically adjusts to varying data sizes, handles collisions efficiently

disadvantages: more complex to implement and splitting buckets requires rehashing and reorganising data

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Write an implementation of insertion sort (in place)

A

Public void insertionSort(array){

for (int i =1; I<array.length;I++){
temp = array[i]
j = i-1

while (j>=0 && array[j] > temp){
array[j+1] = array[j]
j–
}

array[j+1] = temp

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Advantages of separate chaining

A

Handles collisions automatically
buckets can grow dynamically
performs well with a good hash function and low load factor

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What’s a path

A

A path is a sequence of nodes and edges that link 2 nodes

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How to remove a node in an edge list

A

Find the node object
remove from node list
traverse edge list and remove edges involving the node

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Worst and average case for separate chaining

A

Worst case: hash function is poor and all keys map to the same bucket so it’s essentially a linked list
inserting is o(1) and searching/deleting becomes o(n)

average case: hash function distributes keys evenly.
search/delete is o(n/m)
if load factor is low it’s close to o(1)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Approach to BFS

A

Choose a node as first node, mark as visited
discover all neighbours that haven’t been discovered
visit each undiscovered node
once all neighbours are visited move to their discovered neighbours

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Properties of a good hash function

A

Uniform distribution of keys
minimal collisions
fast computation

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Worst and average case for separate chaining

A

Worst case: hash function is poor and all keys map to the same bucket so it’s essentially a linked list
inserting is o(1) and searching/deleting becomes o(n)

average case: hash function distributes keys evenly.
search/delete is o(n/m)
if load factor is low it’s close to o(1)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

definition of a balanced binary search tree

A

In a balanced binary search tree the heights of the left and right sub trees differ by at most 1

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What’s a strongly connected graph

A

A graph is strongly connected when the graph is connected and we respect the directions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

What’s the recursive implementation of post order traversal

A

Public void traverse (BinaryTreeNode node){
if(node.left != null) traverse(node,left)
if(node.right!=null) traverse(node.right)
visit(node.element)
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

What’s the complexity of a rebalancing an AVL tree

A

A single rotation is an o(1) operation
propagating changes is an o(logn) operation as after a rotation the height of the subtree may change which requires updates to the balance factors of its patent, grandparent and so on. In the worst case the propagation may need to travel up the height of the tree which js proportional to o(logn)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Complexity of removal from an edge list

A

O(m) where m is the number of edges

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

What is a bucket overflow

A

A bucket overflows when it can’t store any more key value pairs due to collisions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

How do we label nodes when updating a tree to deal with addition

A

W - the node added
Z - the first unbalanced node above w
X - the child of y with larger height
y- the child of z with larger height

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

how is minimal disruption value determined when deleting a node from a binary search tree

A

It’s the smallest value larger than the deleted node or the largest value smaller than it. So the leftmost node on the right subtree

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

What is a disadvantage of using heuristics

A

They don’t always return the correct or most optimal solution

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

Properties of a good hash function

A

Uniform distribution of keys
minimal collisions
fast computation

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Psuedocode for dijkstras weighed algorithm

A

findShortestWeightedPaths(graph, sourceNode) {
unvisitedNodes = graph.getAllNodes() // Set of all unvisited nodes
for each node in unvisitedNodes {
shortestDistance[node] = infinity // Initialize all distances to infinity
}
shortestDistance[sourceNode] = 0 // Distance to the source node is 0
while unvisitedNodes is not empty {
currentNode = node in unvisitedNodes with smallest shortestDistance
remove currentNode from unvisitedNodes // Mark the current node as visited
for each edge connectedEdge incident on currentNode {
neighborNode = graph.getOppositeNode(connectedEdge, currentNode)
edgeWeight = graph.getEdgeWeight(connectedEdge) // Get the weight of the edge
newDistance = edgeWeight + shortestDistance[currentNode] // Tentative distance
if newDistance < shortestDistance[neighborNode] {
shortestDistance[neighborNode] = newDistance // Update to smaller distance
}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q

Psuedocode for bfs

A

BFS(Graph graph, startNode) {
currentLevel = [startNode] // Start with the list containing the start node
while currentLevel is not empty {
nextLevel = [] // Prepare a new list for the next level of nodes
for each node in currentLevel {
visit(node) // Process or visit the node
for each edge connected to node { // Explore all edges incident on the node
if edge is unexplored { // Check if the edge has been explored
neighborNode = graph.opposite(edge, node) // Find the other endpoint of the edge
if neighborNode is undiscovered { // If the neighbor node hasn’t been discovered yet
label(edge, “discovery”) // Label the edge as a discovery edge
add neighborNode to nextLevel // Add the undiscovered neighbor node to the next level
} else {
label(edge, “cross”) // If the neighbor node has already been discovered, label the edge as a cross edge
}
}
}
}
currentLevel = nextLevel // Move to the next level, update ‘currentLevel’ with the new list of nodes
}
}

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q

Approach to BFS

A

Choose a node as first node, mark as visited
discover all neighbours that haven’t been discovered
visit each undiscovered node
once all neighbours are visited move to their discovered neighbours

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

Advantages of adjacency lists over edge list

A

No need to traverse over entire list
direct access to adjacency lists ensures o(1) removal time per edge

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

Complexity of node removal in an adjacency list

A

O(k) where k is the degree of the node
edge removal is o(1)/edge as we can directly access adjacency lists

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

How to remove a node in an adjacency list

A

Find the node object
remove from node list
remove incident edges:
access the nodes adjacent edge, for each adjacent edge remove the edge itself and update the adjacency list of the other endpoint to remove reference to this edge

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q

Complexity of removal from an edge list

A

O(m) where m is the number of edges

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q

What a weakly connected graph

A

A weakly connected graph is when the graph is connected if we ignore the direction of edges

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
35
Q

Define a connected graph

A

A graph is connected if there’s a path between every pair of nodes

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
36
Q

What’s a subgraph

A

A subset of the original nodes and edges

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
37
Q

Definition of a tree in graphs

A

A tree is an undirected graph in which any 2 nodes are connected by 1 path

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
38
Q

What’s path length

A

Path length is number of edges in a graph

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
39
Q

What’s a path

A

A path is a sequence of nodes and edges that link 2 nodes

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
40
Q

What is the degree of a node in a graph

A

The degree of a graph is the number of edges connected to it
undirected graph: total edges connected to the graph
directed graph: in degree - edges coming into the node
Out degree - edges going out of the node

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
41
Q

What is the degree of a node in a graph

A

The degree of a graph is the number of edges connected to it
undirected graph: total edges connected to the graph
directed graph: in degree - edges coming into the node
Out degree - edges going out of the node

42
Q

What’s a spanning tree

A

A spanning tree is a subset of graph that connects all nodes, has no cycles and contains exactly n-1 edges where n is the number of nodes

43
Q

What are the differences between directed and undirected graphs

A

Directed graphs: edges have a direction going from one way to another
undirected graphs: edges have no direction the connection is bidirectional

44
Q

What are the differences between directed and undirected graphs

A

Directed graphs: edges have a direction going from one way to another
undirected graphs: edges have no direction the connection is bidirectional

45
Q

What’s a graph formally

A

A graph G =(V,E)
V: a set of nodes
E: a set of edges connecting the nodes

46
Q

Properties of a good hash function

A

Uniform distribution of keys
minimal collisions
fast computation

47
Q

Advantages ans disadvantages of hashing over Arrays.

A

Advantages: hashing provides o(1) for search insertion and deletion average compared to arrays o(n) for sorted arrays and o(logn) for unsorted arrays
hash tables can also grow dynamically with resizing or extendible hashing unlike fixed size arrays
hash tables can allocate memory dynamically for buckets whereas arrays allocate memory upfront and is fixed

disadvantages: hash tables don’t maintain the order of elements while arrays order ordered traversal
Hashing works with unique keys and duplicate keys require extra handling unlike arrays where duplicates are inherently supported
arrays allow direct access to elements via indices whereas hashing requires a hash code which adds extra overhead

48
Q

What’s the advantage of using sorted lists in chaining

A

Searching becomes o(log(n/m)) for binary search but adds overhead during insertion

49
Q

What is a bucket overflow

A

A bucket overflows when it can’t store any more key value pairs due to collisions

50
Q

Worst and average case for separate chaining

A

Worst case: hash function is poor and all keys map to the same bucket so it’s essentially a linked list
inserting is o(1) and searching/deleting becomes o(n)

average case: hash function distributes keys evenly.
search/delete is o(n/m)
if load factor is low it’s close to o(1)

51
Q

Advantages and disadvantages of extendible hashing

A

Advantages: don’t need to resize entire table, dynamically adjusts to varying data sizes, handles collisions efficiently

disadvantages: more complex to implement and splitting buckets requires rehashing and reorganising data

52
Q

What is extendible hashing

A

A dynamic hashing technique where the hash code is treated as a bit string and the hash code splits when buckets overflow using more bits to differentiate keys

53
Q

Advantages and disadvantages of secondary hashing

A

Advantages: minimises clustering by providing a better distribution of probes
disadvantages: more complex to implement than quadratic and linear probing and requires careful choice of the second hash function to avoid infinite loops !=0

54
Q

What’s secondary hashing

A

A second hash function is used to calculate the step size for probing

55
Q

Advantages and disadvantages of quadratic probing

A

Advantages: reduces clustering in comparison to linear probing
better distribution of keys in tables

disadvantages: more complex than linear probing and can still fail to resolve collision if table size isn’t a prime number
suffer from secondary clustering where keys with the same initial hash code follow the same sequence

56
Q

Disadvantages of linear probing

A

Leads to primary hashing where groups of filled slots form increasing chances of collisions and slowing future insertions and searches
performance degrades as table fills up

57
Q

Advantages of linear probing

A

Simple to implement and cache friendly due to sequential memory access

58
Q

What is quadratic probing

A

Quadratic probing skips slots in a quadratic pattern.
h(k,i) = (h(k)+i^2) mod m

59
Q

What is linear probing

A

A collision handling technique where the next available slot is searched sequentially;
h(k,i) = (h(k)+i) mod m

60
Q

How does open addressing handle collisions

A

Open adddressing stores key value pairs directly in the hash table. If a collision occurs it probes for the next available slot using techniques such as
linear probing
quadratic probing
secondary hashing

61
Q

Advantages do separate chaining

A

Handles collisions automatically
buckets can grow dynamically
performs well with a good hash function and low load factor

62
Q

How does separate chaining handle collisions

A

Each bucket stores a list (or chain) of key value pairs when keys collide they are added to the same buckets list

63
Q

What’s a collision in hashing

A

A collision occurs when 2 keys hash to the same bucket

64
Q

What’s load factor in a hash table

A

The load factor is the ratio of the number of keys n to the number of buckets m
LF=n/m

65
Q

What is a bucket

A

A bucket is a container at an array index where one or more key value pairs may be stored

66
Q

What is hashing

A

Hashing maps keys to values using a hash function enabling efficient data storage and retrieval

67
Q

What’s the complexity of a rebalancing an AVL tree

A

A single rotation is an o(1) operation
propagating changes is an o(logn) operation as after a rotation the height of the subtree may change which requires updates to the balance factors of its patent, grandparent and so on. In the worst case the propagation may need to travel up the height of the tree which js proportional to o(logn)

68
Q

What’s the balance factor in an AVL tree

A

What’s the balance factor in an AVL tree

69
Q

What’s the balance factor in an AVL tree

A

The difference in heights between the left and right subtree of a node

70
Q

When is rebalancing needed in a BST

A

After a node is added/removed the balance factor of any node isn’t within [-1,1]

71
Q

how is minimal disruption value determined when deleting a node from a binary search tree

A

It’s the smallest value larger than the deleted node or the largest value smaller than it. So the leftmost node on the right subtree

72
Q

What are the cases to consider when deleting a node from a binary tree

A

Leaf node
node with one child
node with 2 children

73
Q

What is the complexity of searching in a balanced vs unbalanced binary search tree and why

A

In a balanced binary search tree with n nodes its height is log base 2 n
eaxh step the target value is compared with the current nodes value and move to either the left or right node. Each step halves the search space. The search path is proportional to the height of the tree so the search time is also o(Logn)

if the tree becomes unbalanced its height can grow as large as n in the worst case. Its time complexity becomes O(n) as you may have to visit every node to find the target

74
Q

What is the key invariant of a binary search tree

A

For each node all labels in the left subtree are less than the nodes label and all labels in the right subtree are greater

75
Q

Compare the strategies of choosing a pivot between first, last or randomly selected element or median of 3 values

A

First/ last: is simple to implement but can lead to unbalanced partitions (eg worst case o(n^2)) if the list is already sorted

median: improves balance and avoids worst case scenarios but adds extra computation to find the median

randomly: generally ensures balanced partitions on average, avoiding input specific patterns and is computationally cheap

76
Q

Compare structural vs value driven algorithms and their advantages/ disadvantages

A

Structural algorithms like merge sort:
approach: divide the list based on structure (eg splitting by size)
Advantages: predictable performance (o(nlogn)) for all cases and no reliance on input values
disadvantages: uses extra space due to auxiliary arrays

value driven algos:
approach: divide based on value comparisons
advantages: can be done in place using o(1) memory
disadvantages: worst case performance is o(n^2) when partitions are imbalanced and requires careful pivot selection

77
Q

What’s the time complexity of merge sort and why

A

Splitting is a log n operation and merging is o(n) operation making it o(nlogn)

78
Q

How does merge sort use divide and conquer

A

It splits the list into two halves, recursively sorts them and merges the sorted halves

79
Q

Complexity of selection sort and why

A

Selection sort is o(n^2) because it performs roughly n comparisons for each element since there are n elements the number of comparisons grows quadratically

80
Q

What is the idea behind selection sort

A

Repeatedly find the smallest element and place it at the beginning of the list

81
Q

Write an implementation of insertion sort (in place)

A

Public void insertionSort(array){

for (int i =1; I<array.length;I++){
temp = array[i]
j = i-1

while (j>=0 && array[j] > temp){
array[j+1] = array[j]
j–
}

array[j+1] = temp

82
Q

What is the time complexity of insertion sort in its average, best and worst case and why

A

It’s average case is o(n^2) because well roughly have to do n/4 swaps for n elements giving you an average complexity of o(n^2)

its worst case is o(n^2) and it occurs when it’s reverse sorted. For each of the n elements it performs up to n shifts

its best case is o(n) this is when the list is sorted because each element only needs a single comparison to check whether it’s in the right place

83
Q

What is a disadvantage of using heuristics

A

They don’t always return the correct or most optimal solution

84
Q

Why are heuristics used

A

They provide faster approximate solutions. Useful for when algorithms take too long or fail to terminate

85
Q

Difference between an algorithm and a heuristic

A

Algorithms terminate for finite inputs heuristics aren’t always guaranteed to terminate and give approximate results

86
Q

How are expressions derived in postfix traversal

A

Operators are after operands and derived using post order traversal

87
Q

How are expressions derived in infix notation

A

Infix notation uses in order traversal and brackets are used to surround each sub expression. Operators are inline with operands

88
Q

How are expressions derived in prefix notation

A

Prefix notation uses pre order traversal, operators are before operands

89
Q

Implement in order traversal recursively

A

Public void traverse(BinaryTreeNode node){
if(node.left!=null) traverse(node.left)
visit(node.element)
if(node.right!=null) traverse(node.right)
}

90
Q

How does in order traversal work

A

Visit the first child them the node then the next child

91
Q

What’s the recursive implementation of post order traversal

A

Public void traverse (BinaryTreeNode node){
if(node.left != null) traverse(node,left)
if(node.right!=null) traverse(node.right)
visit(node.element)
}

92
Q

How does post order tree traversal work

A

Visit the children then visit the node

93
Q

What’s the recursive implementation of preorder tree traversal

A

public void traverse(BinaryTreeNode node){
visit(node.element)
if(node.left!=null) traverse(node.left)
if(node.right!=null) traverse(node.right)

}

private void visit(Object element){
print(element + “,”)
}

94
Q

How does pre order tree traversal work

A

Visit the node then visit that nodes children

95
Q

Write selection sort in Java

A

for (int I =0; I< array.length-1;I++){
int min = I
for (int j = i+1; j<array.length;j++){
if (array[min] > array[j]){
min = j
}
}
int temp = array[i]
array[i]=array[min]
array[min] = temp
}

96
Q

Write bubble sort

A

For (int I =0; I < array.length: I++ ){
For (int j =0;j<array.length-I-1;j++){
if(array[j] > array[j+1]){
int temp = array[j]
array[j]=array[j+1]
array[j+1] = temp
}
}
}

97
Q

Disadvantages of array based stack implementation

A

Arrays have a fixed size so the stack can’t be resized

the user could easily overestimate or underestimate the amount of elements their stack will need to store which could lead to memory wasteage or unexpected errors

98
Q

What are some advantages of an array based stack implementation

A

The implementation of an array based search is simple since it only requires an index to keep track of the top element

pushing and popping from an array based stack runs in o(1) time so it’s efficient

array based implementations have lower memory overhead as they don’t need to store references to pointers

99
Q

A stack is a LIFO data structure what does this mean

A

this means the last element that is added to the stack is the first that is popped out

100
Q

write an array based stack implementation to the following interface
public interface IStack{
void push( T element) throws StackOverflowException
T pop() throws StackEmptyException
T top() throws StackEmptyException
int size()
Boolean isEmpty()
void clear()
}

A

public class ArrayStack implements IStack{
private int size;
private T[] elements;

public ArrayStack(int maxSize){
size =0
elements = new (T[]) Object[maxSize]
}

Public void push ( T element){
if ( size < elements.length){
elements[size++] = element
} else{
throw new StackOverflowException();
}

public T pop(){
if (isEmpty()){
throw new StackEmptyException
} else{
size-=1;
return elements[size-1]

}

public T top(){
if(isEmpty()){
throw new StackEmptyException()
} else{
return elements[size-1]
}
}

public Boolean isEmpty(){
return size =0;
}

public void clear(){
size =0;
}

101
Q

Implement a queue using a singly linked list define the generic ListNode classes and queue classes as well. Use the interface

interface IQueue<T> {
void enqueue(T element )
T dequeue() throws queueemptyexception
int size()
boolean isEmpty()
}</T>

A

public class ListNode<T>{
public T element
public ListNode<T> next</T></T>

public ListNode(element){
this(element,null)
}

public ListNode(T element, ListNode<T>next){
this.element=element
this.next = next
}</T>

public class Queue<T> implements IQueue {
private ListNode<T> front
private ListNode<T> back
private int size =0</T></T></T>

public Queue(){
this.front = null;
this.back = null;
size =0;
}

public void enqueue ( T element){

ListNode<T> newNode = new ListNode(element)</T>

If ( isEmpty()){

front = newNode
back = front
} else{
back.next = newNode
back = back.next
}
size++
}

public T dequeue() throws QueueEmptyException(){
T frontElement = front.element
front = front.next
size- -
return front.element;
}

public int size(){
return size
}

public Boolean IsEmpty(){
return size == 0
}