【问题标题】:Traversing binary search tree, how to advoid code duplication遍历二叉搜索树,如何避免代码重复
【发布时间】:2019-12-12 15:45:37
【问题描述】:

我一直在做这个小程序。它从文件中读取数据(成员)并将其存储在二叉搜索树中。有两个功能,打印所有成员和打印所有成员但只使用相同的船类。为此,它遍历树。

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);
    }
}

结构定义:

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;

对我来说,遍历似乎是代码重复。我试图将这些函数合并为一个,但每个函数都采用不同的参数。有没有办法解决这个问题,还是必须分开?

【问题讨论】:

  • 请避免在 typedef 中包含*。知道某物是否是指针非常重要。这不应该对你的读者隐藏。

标签: c function binary-search-tree traversal code-duplication


【解决方案1】:

将支票移至访问者,并让访问者接受传递给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);

将节点的深度传递给访问者通常很有用,所以我也添加了它。

【讨论】:

  • 耻辱 c 没有闭包
  • @Ian Ringrose,是的。我试图找到一种提及方式,而不会让事情变得太复杂
  • 这就像向只经历过数小时动力运输的人解释特斯拉 Model 3。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-09
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多