add breadth-first search function to find client nodes in a tree

This commit is contained in:
Akos Horvath 2023-05-26 20:33:59 +02:00
parent 92a5dc5cf1
commit c5990665f5
2 changed files with 67 additions and 3 deletions

68
util.c
View File

@ -50,9 +50,7 @@ void wm_nodearray_push(NodeArray *arr, TreeNode node)
bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret)
{
assert(arr);
if (!ret || !arr)
return false;
assert(ret);
if (arr->size == 0)
return false;
@ -62,6 +60,21 @@ bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret)
return true;
}
bool wm_nodearray_pop_front(NodeArray *arr, TreeNode *ret)
{
assert(arr);
assert(ret);
if (arr->size == 0)
return false;
*ret = arr->nodes[0];
arr->size--;
memcpy(arr->nodes, arr->nodes+1, arr->size * sizeof(TreeNode));
return true;
}
bool wm_nodearray_remove(NodeArray *arr, size_t index)
{
assert(arr);
@ -91,6 +104,55 @@ void wm_nodearray_free(NodeArray *arr)
free(arr->nodes);
}
// breadth-first search for finding client nodes in tree
ClientArray wm_nodearray_find_clients(TreeNode *root)
{
assert(root);
/* storing visited nodes in an array and searching is
not optimal, but this is not a performance-critical function. */
NodeArray visited = wm_nodearray_new();
wm_nodearray_push(&visited, *root);
NodeArray queue = wm_nodearray_new();
ClientArray clients = wm_clientarray_new();
wm_nodearray_push(&queue, *root);
while (queue.size > 0) {
TreeNode node;
if (!wm_nodearray_pop_front(&queue, &node))
goto ret;
if (node.type == NODE_CLIENT)
wm_clientarray_push(&clients, *node.client);
for (int i = 0; i < node.children.size; i++) {
TreeNode child_node = node.children.nodes[i];
bool _visited = false;
for (int j = 0; j < visited.size; j++) {
// this comparison may not work
if (visited.nodes[j].children.nodes == child_node.children.nodes) {
_visited = true;
break;
}
}
if (!_visited) {
wm_nodearray_push(&visited, child_node);
wm_nodearray_push(&queue, child_node);
}
}
}
ret:
wm_nodearray_free(&visited);
wm_nodearray_free(&queue);
return clients;
}
ClientArray wm_clientarray_new()
{
ClientArray arr;

2
util.h
View File

@ -54,8 +54,10 @@ void wm_treenode_init(TreeNode *node, NodeType type, TreeNode *parent);
NodeArray wm_nodearray_new();
void wm_nodearray_push(NodeArray *arr, TreeNode node);
bool wm_nodearray_pop(NodeArray *arr, TreeNode *ret);
bool wm_nodearray_pop_front(NodeArray *arr, TreeNode *ret);
bool wm_nodearray_remove(NodeArray *arr, size_t index);
void wm_nodearray_free(NodeArray *arr);
ClientArray wm_nodearray_find_clients(TreeNode *root);
ClientArray wm_clientarray_new();
void wm_clientarray_push(ClientArray *arr, Client node);