我想在C中实现两个在BST上运行的通用函数,并将其节点的键存储在一个返回给调用者的单链表中。一个函数存储BST的所有密钥,另一个函数仅存储给定范围内的密钥。这两个函数都执行“按顺序”访问,这意味着密钥以升序存储,并在列表中插入尾部。
由于我没有发现任何伪代码,我试图找到一种方法来实现这一点,但目前它不起作用,Valgrind警告我几个问题,如“条件跳转或移动取决于未初始化的价值“。 我试图将列表从一个函数转移到另一个函数或者一些错误的malloc()或free()的方式可能有问题。
我还有一个关于如何改进整个代码的问题:不是使用两个非常相似但最终做不同事情的不同函数,根据输入使用只做一个不同的事情可能会很棒它收到了。必须存储的键范围包括“low_key”和“high_key”,以便两者之间的所有键都有效。 由于这两个键是void的指针,如果它们都被传递为NULL,则可能意味着我想存储BST的所有键。这是正确的还是会导致意想不到的结果?
list_t
是指向列表节点的指针(指向node_t
); node_t
是列表的一个节点,它指向一个关键字段; bst_t
是指向主BST结构的指针,该结构指向根节点(bst_node_t
); bst_node_t
是BST的节点; comparator_t
是指向比较通用数据的函数的指针,存储在主BST结构中;如果第一个元素> 1,则返回1第二个元素,否则为-1,如果它们相等则为0; low_key
是键范围的下限,high_key
是上限。存储所有密钥的代码
list_t bst_keys_all(const bst_t tree)
{
if (bst_is_empty(tree))
return NULL;
// pointer to head
list_t list = malloc(sizeof(node_t));
if (list == NULL)
return NULL;
// head passed as pointer to pointer to emulate pass by reference
traverse1(tree->root, &list);
return list;
}
void traverse1(node_t *node, list_t *list)
{
if (node == NULL)
return;
traverse1(node->left, list);
append(node, list);
traverse1(node->right, list);
}
void append(bst_node_t *tree_node, list_t *head)
{
list_t new_node = malloc(sizeof(node_t));
list_t last_node = *head;
new_node->key = tree_node->key;
new_node->next = NULL;
if (*head == NULL) {
*head = new_node;
return;
}
while (last_node != NULL) {
last_node = last_node->next;
}
last_node->next = new_node;
free(new_node);
return;
}
仅在一个范围内存储密钥的代码
list_t bst_keys_range(const bst_t tree, const void *low_key, const void *high_key)
{
if (bst_is_empty(tree))
return NULL;
list_t list = malloc(sizeof(node_t));
if (list == NULL)
return NULL;
// head of the list passed as pointer to pointer again
// key_cmp is a field of the main bst structure that points to a comparator_t function
traverse2(tree->root, &list, low_key, high_key, tree->key_cmp);
return list;
}
void traverse2(node_t *node, list_t *list, const void *low_key, const void *high_key, comparator_t cmp)
{
if (node == NULL)
return;
if (cmp(low_key, node->key) < 0)
traverse2(node->left, list, low_key, high_key, cmp);
if (cmp(low_key, node->key) <= 0 && cmp(high_key, node->key) >= 0)
append(node, list); // it's the same function used in the code above
if (cmp(high_key, node->key) > 0)
traverse2(node->right, list, low_key, high_key, cmp);
}