You are on page 1of 28

COP3502 Final Exam Study Guide

Made by SI Leader Yamil Casarreal

Congratulations on making it this far into CS1! This course is not easy, but you stuck through it
and worked hard to get this far. You’re almost at the finish line, so finish strong! And for my
fellow CS majors, you still have to run another mile for the FE (haha). I created this study guide
not only as an effective study tool, but also as a starting point of where to begin studying. I
want to make this clear just because you master this study guide does not mean you’ll get
100% on the exam. I encourage you to do the exercises Dr. Ahmed has in the modules section
of the course alongside doing this study guide. And to be honest, I copied and pasted some of
those questions into this study guide (so I can finally force you to them). You all have taken
several quizzes and one exam by now, so you already know he bases his questions on those
exercises. So even if they weren’t assigned to you, do them anyway!
Most of the questions are going to be a little more on the conceptual side. Why you may ask?
Well, if you have a strong knowledge of the concepts, you can easily do the code. If any of you
have attended my sessions, you know we tackled difficult coding problems by just knowing the
concepts alone. Also, I don’t have enough time during the final review session to go in depth
with coding questions. At the end of the day, you as a programmer are pretty much a
translator. We translate everything we learned conceptually into code. And with all the
programming assignments you have done so far, I promise you’ve gotten pretty good at it.
For the CS majors, I’m sorry, but the grind doesn’t stop after the final exam. Keep studying and
constantly do past FE questions over the break so you can pass the FE on your first try and be
done with it. If you need any help at all or have questions, don’t hesitate to message me on
discord at “rocketmanjoey”.
My advice for the final exam: chill and be calm. If you can’t answer a question within a minute,
skip it and come back to it later. If you get done early, redo the exam and check over your work.
DON’T LEAVE ANYTHING BLANK!!!!!!!!

Good luck!
Yamil Casarreal
Table of Contents
• Summations
• Algorithm Analysis
• Recurrence Relations
• Sorting
• Binary Search Trees
• AVL Trees
• Tries
• Heaps
• Hash Tables
• Binary Operators
Summations
Find the ordered pair of values (a, b) that satisfy the following:

What is the closed form of the following summation in terms of n?

Determine the following summation in terms of n (assume n is a positive integer 2 or greater),


expressing your answer in the form an3 + bn2 + cn, where a, b and c are rational numbers. (Hint: Try
rewriting the summation into an equivalent form that generates less algebra when solving.)

Write the closed form solution in term of N for the summation:

Hint: Formula -
Algorithm Analysis
Determine the Big O run time of the following code fragments and prove it (Hint: Summations can help)

for (k = 1; k <= n/2; k++) {

sum = sum + 5;

for (j = 1; j <= n*n; j++) {

delta = delta + 1;

for (k = 1; k <= n/2; k++) {

sum = sum + 5;

for (j = 1; j <= n*n; j++) {

delta = delta + 1;

int func2(int n) {

int i, j, x = 0;

for (i = 1; i <= n; i++) {

for (j = 1; j <= n; j++) {

x++;

return x;

}
int func3(int n) {

sum = 0;

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

for (j = 0; j < n * n; j++) {

sum++;

return sum;

int func3(int n) {

bigNumber = 0;

for (i = 100; i <= 2n; i++) {

for (j = 1; j < n * n; j++) {

bigNumber += i*n + j*n;

return bigNumber;

}
int function7(int A[], int B[], int n) {

int i=0,j;

while (i < n) {

j=0;

while (j < n && A[i] > B[j]) j++;

i++;

return j;

}
Recurrence Relations
Solve the Following Recurrence Relations and find the BigO

𝑇(𝑛) = 𝑇(𝑛 − 1) + 2, 𝑇(1) = 1

𝑇(𝑛) = 2𝑇(𝑛/2) + 𝑛, 𝑇(1) = 1

𝑇(𝑛) = 2𝑇(𝑛/2) + 1, 𝑇(1) = 1

𝑇(𝑛) = 𝑇(𝑛 − 1) + 𝑛, 𝑇(1) = 1


Give the following code of merge sort, write the recurrence relation and solve it to determine the Big O.
Sorting
For this section, use the following array for each question: [1, 8, 4, 5, 6, 3, 2, 7]

Which sorting algorithm(s) is/are, on average, O(n log n)?

Which sorting algorithm(s) is/are, on average, O(n2 )?

Which sorting algorithm(s) is/are always O(n2 )?

Show the contents of the array after each iteration of Insertion Sort.

Show the contents of the array after each iteration of Bubble Sort.

Show the contents of the array after each iteration of Selection Sort.

How many merge operations will be performed if we ran merge sort?

Using the number 4 as our pivot, show the state of the array after each swap when running quick sort.
You are trying to create a function that utilizes merge sort and insertion sort. You want use merge sort
as long as your array size is bigger than sortingRange, but uses insertion sort otherwise, assume you are
given a function called void merge(int *values, int start, int mid, int end) to perform merge operation
and void insertionSort(int *values, int numOfElements) to perform insertion sort.

Here is the function prototype for you to fill:

void mergeInsertionSort(int *values, int start, int end, int sortingRange);

(Not a question)Please review the code for all the sorting algorithms, especially quick sort and merge
sort!!!!!!!!!!!
Binary Search Trees
Draw the binary search tree that results from inserting the following values into an initially empty binary
search tree in the following order: 50, 27, 16, 88, 34, 65, 52, 77, 93, 4, 12, 29, 44, 92

What are the outputs of a preorder, inorder and postorder traversal of the final binary search tree
drawn above?

Preorder:

Inorder:

Postorder:

Draw the above BST after deleting the node containing 50.

Write a function which returns the number of leaf nodes in a binary search tree. The prototype is below:
int numLeafNodes(struct treenode* root) {

}
Write a function which returns the smallest value stored in a non-empty binary search
tree. The prototype is below:

int minVal(struct treenode* root) {

Write a function that operates on a binary tree of integers. Your function should sum up the
all of the odd numbers in the tree EXCEPT for the numbers in leaf nodes, which should instead
be ignored. Make use of the function prototype shown below.
int sum_nonleaf_odd(struct treenode* p);

Write a recursive function to compute the height of a tree, defined as the length of the longest path
from the root to a leaf node. For the purposes of this problem a tree with only one node has height 1
and an empty tree has height 0.
int height(struct treenode* root);
AVL Trees

Draw how we can resolve any AVL tree imbalance. Use the A, B, C nodes from the slides and subtrees
T0-T3.

Show the AVL tree after inserting the following elements in order: 50, 30, 75, 80, 92

Show the AVL tree after inserting the following elements in order: 50, 25, 12, 80, 90, 37, 45, 18, 19, 6
Draw the result of deleting the designated value from the AVL trees shown below:
Tries
Consider inserting the following words into an initially empty trie, where nodes are created ONLY if they
are necessary. Note that an empty trie is a NULL pointer and has zero nodes. How many nodes will be
created after all these words are inserted, including the root node?

RAY

TARS

RAT

RA

DO

LEET

DOG

DART

LET

TART

LEE

(Note that while making a drawing to help you obtain your answer is both acceptable and encouraged,
you must give the actual number of nodes too and not just the drawing.)
For the next two questions, utilize this struct:

typedef struct trie {

int isWord;

struct trie *letters[26];

}trie;

Given the function prototype, write a function that inserts a word into a trie. len represents the length
of the word you are trying to insert, k will be called with the number 0.

void insert(trie *root, int len, int k, char *word)

Given the function prototype, write a function that returns 1 if a word is in the trie or 0 if it is not.

int find(trie *root, int len, int k, char *word);


Heaps
Show the result of inserting the number 11 into the min-heap shown below:

Show the result of removing the minimum element from the resulting tree of the previous question:

Show the array representation of the resulting min-heap of the previous question:
Run the heapify function for the following values:

In an array-based implementation of a Heap, the left-child of the left-child of the node at


index i, if it exists, can be found at what array location?

In an array-based implementation of a Heap, the right-child of the right-child of the node at


index i, if it exists, can be found at what array location?
Utilize the struct for the next two questions:

typedef Struct heapStruct{

int *heapArray;

int capacity;

int size;

}heapStruct;

Complete the percolateUp function that performs percolate up on the heap to by h on the node stored
in index (assume we are working with minheap):

void percolateUp(heapStruct *h, int index){

}
Complete the percolateDown function that performs percolate down on the heap to by h on the node
stored in index (assume we’re working with minheap):

You can make use of the function below:

int min(int child1, int child1Index, int child2, int child2Index); //returns the index of the child with the
minimum number

void percolateDown(heapStruct *h, int index){

}
Hash Tables
Consider a hash table that uses the linear probing technique with the following hash function f(x) =
(3x+2)%11. (The hash table is of size 11.) If we insert the values 5, 12, 6, 8, 1, 15, and 20 into the table, in
that order, show where these values would end up in the table?

Do the same question as above, but this time use the quadratic probing strategy.

Do the question above, but draw a picture of what the hash table would look like if
separate chaining hashing was used.
Consider the following strings and their corresponding hash values, which have been
generated by some hash function:
hash(“squiggle”) = 301
hash(“giggle”) = 174
hash(“haggle”) = 431
hash(“gaggle”) = 263
hash(“straggle”) = 361

Insert the strings above into the following hash table using quadratic probing. In doing

so, insert them in the order given above (i.e., starting with “squiggle”, then “giggle”,

and so on). Note that the hash table’s length is 11 (not 10)
Binary Operators
Determine the value of each of these arithmetic expressions in C.
• 22 | 87
• 13 & 56
• 45 ^ 64
• 12 << 6
• 156 >> 4

Write a recursive function that returns the number of bits set to 1 in the binary representation of its
input parameter, n.

Write a function that returns 1 if a number is even or 0 if it is odd utilizing only binary operators (no
using % 2....)

Write a function that returns the lowest bit set to 1:


int lowestBit(int n){

Write a function that returns the highest bit set to 1:


int highestBit(int n){

}
An organization has 30 groups of employees, labeled as group 0, 1, 2, …, 29. Each individual employee is
assigned to some subset of those groups. The set of groups to which an employee belongs can be stored
in a single integer, called the employee's ACCESS CODE, based on the bits of that integer. For example,
an employee in groups 0, 3, 13 and 18 would have ACCESS CODE 2 0 + 23 + 213 + 218 (this is equal to
270345.) There are several shared drives at the organization. Each shared drive is accessible by any
employees in a specified set of employee groups. The ACCESS CODE of a drive is specified exactly as that
of an employee. If all employees who belong to either groups 2, 3 or 6 should have access to a shared
drive, then that drive's access code is 22 + 23 + 2 6 (76). An employee with ACCESS CODE 270345 would
have access to a drive with ACCESS CODE 76, since the employee is part of group 3, and all employees in
group 3 get access to the drive. Write a function that takes in an employee's access code, empCode, (as
a single integer), an array of integers (driveCodes) storing the access codes of every shared drive in the
organization, and the length of that array (numDrives), and returns the number of the shared drives that
the employee with the given access code has access to

int numDrivesAccess(int empCode, int* driveCodes, int numDrives) {

}
There are a total of 25 cards, numbered 0 through 24. We can represent a set of cards with a single
integer by setting the ith bit to 1 if the set contains card i, and setting the bit to 0 otherwise. For
example, the set of cards {2,6, 7} would be stored as the integer 196, since 196 = 27 + 26 + 22. Two sets
of cards are disjoint, if and only if no card appears in both sets. Complete the function below so that it
returns 1 if the sets of cards represented by the integers set1 and set2 are disjoint, and returns 0 if they
are not disjoint. (For example, disjoint(196, 49) should return 1 because 49 = 25 + 24 + 20, and there is
no common value in the two sets {2, 6, 7} and {0, 4, 5}. On the other hand, disjoint(196, 30) should
return 0 because 30 = 24 + 23 + 22 + 21, so that card number 2 is included in both sets 196 and set 30.)

// Pre-condition: set1 and set2 are bitmasks in between 0 and (1<<25)-1.

// Post-condition: Returns 1 if the two bitmasks are disjoint, meaning that the

// sets they represent don't have any items in common, and returns 0 otherwise, if

// the two represented sets do have common items.


You have reached the end of the topics we have covered

To congratulate your efforts, here is a picture of my dog, Rogue

You might also like