1

I have been working on this small program. It reads data(members) from a file and stores it in a binary search tree. There are two features, print all the members and print all members but only with the same boat class. To achieve this it traverses the tree.

void traverse_tree(member_node member, void(*print_members)(member_node)) {

        print_members(member);

        if (member->left != NULL) {
            traverse_tree(member->left, print_members);
        }

        if (member->right != NULL) {
            traverse_tree(member->right, print_members);
        }
    }

void list_by_boat_class(member_node member, char *boat_class, void(*print_members)(member_node)) {

    if (strcmp(member->boat_class, boat_class) == 0) {
        print_members(member);

    }
    if (member->left != NULL) {
        list_by_boat_class(member->left, boat_class, print_members);
    }
    if (member->right != NULL) {
        list_by_boat_class(member->right, boat_class, print_members);
    }
}

Struct def:

typedef struct member * member_node;

typedef struct member{
    char name[NAME];
    char personal_names[PERSONAL_NAMES];
    int mem_id;
    char email[EMAIL];
    char boat_class[BOAT_CLASS];
    char boat_name[BOAT_NAME];

    struct member * left;
    struct member * right;
}member;

The traversing seems like a code duplication to me. I tried to merge these functions in to one but each function takes different arguments. Is there any solution to this or it has to stay separated?

Ian Ringrose
  • 51,220
  • 55
  • 213
  • 317
  • Please avoid including the `*` in the typedef. It's very important to know whether something is a pointer or not. This should not be hidden from your readers. – ikegami Dec 12 '19 at 16:02

1 Answers1

2

Move the check into the visitor, and have the visitor accept an extra argument passed to traverse_tree.

void print_member(member *member, int depth, void *data) {
    ...
}

void print_member_of_boat_class(member *member, int depth, void *data) {
    const char *boat_class = data;
    if (strcmp(member->boat_class, boat_class))
        return;

    print_member(member, depth, NULL);
}

void traverse_tree(member *member, int depth, void (*visitor)(member*), void *data) {
    visitor(member, depth, data);
    ++depth;
    if (member->left)
        traverse_tree(member->left, depth, print_members, data);
    if (member->right)
        traverse_tree(member->right, depth, print_members, data);
}

traverse_tree(tree, 0, print_member, NULL);

traverse_tree(tree, 0, print_member_of_boat_class, boat_class);

Passing a node's depth to the visitor is often useful, so I added that too.

ikegami
  • 367,544
  • 15
  • 269
  • 518