Week 3 - Algorithms
Last updated
Last updated
This is CS50 Week 3. I will go through my summary of Week 3's content.
Basically, this method starts at the beginning and select the smallest till the end and then swap it with the current selection.
Its time complexity is . Inspiration from shorts:
The idea behind selection sort: The idea of selection sort is to find the smallest unsorted element and add it to the end of the sorted list.
In pseudocode:
This method sorts the largest number to the end until the beginning.
The idea behind bubble sort: The idea of bubble sort is to move higher valued elements generally towards the right and lower value elements generally towards the left.
In pseudocode:
This method takes twice the memory space.
The idea behind merge sort: The idea of merge sort is to sort smaller arrays and then combine those arrays together (merge them) in sorted order.
To debug recursive function more effectively, there is a field called Call Stack.
The return
inside a function call only ends the given function call only. It won't terminate the whole program.
Just keep in mind the best and worst case time complexity of these three sort algorithms. That's enough.
If the user inputs an invalid input, the vote will be wasted.
We must print out all the candidates with max
votes.
Vote
Print Winners
In the print_winners()
, we need two loops, one for finding the max votes and another for printing all the candidates with that max votes if we don't want to increase the space complexity, like using an array to record the index of the candidates with max votes.
In the second problem about plurality, we may face a problem that there may be several winners. To deal with that problem, we assign the rank to each candidate the voter votes to.
preferences[i][j]
indicates that voter i
's rank
th choice is the value of preferences[i][j]
th candidate. (We assume that preferences[i][0]
is the first choice).
Thanks to the introduction of rank
, our election may have only one winner. If not, we need to do the elimination.
Record preference if vote is valid (bool vote(int voter, int rank, string name)
)
Tabulate votes for non-eliminated candidates (void tabulate(void)
)
Print the winner of the election, if there is one (bool print_winner(void)
)
Return the minimum number of votes any remaining candidate has (int find_min(void)
)
Decide whether the election is a tie (bool is_tie(int min)
)
Eliminate the candidate (or candidates) in last place (void eliminate(int min)
)
Nothing much to take away since it is a very specific probelm. What I want to say is to follow the problem instructions carefully!
The integer preferences[i][j]
will represent the number of voters who prefer candidate i
over candidate j
.
The file also defines another two-dimensional array, called locked
, which will represent the candidate graph. locked
is a boolean array, so locked[i][j]
being true represents the existence of an edge pointing from candidate i
to candidate j
; false means there is no edge. (If curious, this representation of a graph is known as an “adjacency matrix”).
The struct
called pair
is used to represent a pair of candidates: each pair includes the winner
's candidate index and the loser
's candidate index. (Both of the index are integer)
There is an array called ranks
, where ranks[i]
is the index of the candidate who is the i
th preference for the voter. (We will update the rank at each iteration of a new voter)
Update ranks given a new vote (bool vote(int rank, string name, int ranks[])
)
Update preferences given one voter's ranks (void record_preferences(int ranks[])
)
Method 1
Method 2
Record pairs of candidates where one is preferred over the other (void add_pairs(void)
)
Sort pairs in decreasing order by strength of victory (void sort_pairs(void)
)
The criteria for comparison is preferences[i][j]
, which is also the strength of victory.
Bubble sort. Just a normal Buuble sort implementation would be okie but remember that in this problem, we need to move the smallest number towards the right.
Lock pairs into the candidate graph in order, without creating cycles (void lock_pairs(void)
)
This problem can be regarded as a very classic problem: determine whether there is a cycle in a directed graph. But in this probelm it's a little different, there is only one edge between two vertices.
Method 1
This method will use DFS and Recursion to judge the cycle in the graph. (Note that this method may not apply to general directed graph).
Lock the pairs (...lock_pairs(...)
)
Check whether there is a loop in the graph (loop_check(int start)
)
Print the winner of the election (void print_winner(void)
) For a specific candidate j
, if with all the other candidates (iterating from i
), the locked[j][i]
is false, then candidate j
is the winner. Otherwise, there is no winner.
loop_check()
If a recursion function, if you want to return true after reaching a specific requirement, you must return true from all the calls. That means you must add a line if (recursion_function_call) return true
. This is very important.
Its time complexity is also. Inspiration from shorts:
Its time complexity is . Inspiration from shorts: