Reputation: 39
I am fairly new to C and cannot figure out how to make the function number_within_k_degrees()
less redundant. It visits the same nodes of the graph again and again, even though they may have already been visited. I thought to remove the initial setting of all values to false
to reduce it somewhat, however I don't think that does much. Any tips on how to reduce or eliminate the redundant work would be very helpful. Thanks
void find_reachable_recursive(struct person *current, int steps_remaining,
bool *reachable){
// mark current root person as reachable
reachable[person_get_index(current)] = true;
// now deal with this person's acquaintances
if (steps_remaining > 0){
int num_known = person_get_num_known(current);
for (int i = 0; i < num_known; i++){
struct person *acquaintance = person_get_acquaintance(current, i);
find_reachable_recursive(acquaintance, steps_remaining - 1, reachable);
}
}
}
// computes the number of people within k degrees of the start person
int number_within_k_degrees(struct person *start, int total_people, int k){
bool *reachable;
int count;
// maintain a boolean flag for each person indicating if they are visited
reachable = malloc(sizeof(bool) * total_people);
for (int i = 0; i < total_people; i++){
reachable[i] = false;
}
// now search for all people who are reachable with k steps
find_reachable_recursive(start, k, reachable);
// all visited people are marked reachable, so count them
count = 0;
for (int i = 0; i < total_people; i++){
if (reachable[i] == true){
count++;
}
}
return count;
}
Upvotes: 1
Views: 73
Reputation: 546005
I thought to remove the initial setting of all values to
false
to reduce it somewhat
That’s obviously a very bad idea: it needs to be initialised (to false
) for correctness.
The real problem is that you never test whether a node has been visited yet. Since a note that was already visited does not need to be processed again, you can abort immediately:
void find_reachable_recursive(struct person *current, int steps_remaining,
bool *reachable){
const int pindex = person_get_index(current);
if (reachable[pindex]) return;
// mark current root person as reachable
reachable[pindex] = true;
… rest of the code
Some further suggestions for improvements:
malloc
followed by setting values to false
in a a loop, use calloc
.if (reachable[i] == true)
is redundant, and should be written as if (reachable[i])
instead.Upvotes: 1