mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 19:17:44 +00:00
LibC: Implement tfind and tsearch
This commit is contained in:
parent
d045181375
commit
7448626bae
6 changed files with 265 additions and 0 deletions
92
Userland/Libraries/LibC/search.cpp
Normal file
92
Userland/Libraries/LibC/search.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (c) 2021, the SerenityOS developers.
|
||||
* Copyright (c) 2021, Tim Schumacher <timschumi@gmx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/Format.h>
|
||||
#include <bits/search.h>
|
||||
#include <search.h>
|
||||
|
||||
struct search_tree_node* new_tree_node(const void* key)
|
||||
{
|
||||
auto* node = static_cast<struct search_tree_node*>(malloc(sizeof(struct search_tree_node)));
|
||||
|
||||
if (!node)
|
||||
return nullptr;
|
||||
|
||||
node->key = key;
|
||||
node->left = nullptr;
|
||||
node->right = nullptr;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
void delete_node_recursive(struct search_tree_node* node)
|
||||
{
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
delete_node_recursive(node->left);
|
||||
delete_node_recursive(node->right);
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void* tsearch(const void* key, void** rootp, int (*comparator)(const void*, const void*))
|
||||
{
|
||||
if (!rootp)
|
||||
return nullptr;
|
||||
|
||||
if (!*rootp) {
|
||||
*rootp = new_tree_node(key);
|
||||
return *rootp;
|
||||
}
|
||||
|
||||
auto node = static_cast<struct search_tree_node*>(*rootp);
|
||||
|
||||
while (node != nullptr) {
|
||||
auto comp = comparator(key, node->key);
|
||||
|
||||
if (comp < 0 && node->left) {
|
||||
node = node->left;
|
||||
} else if (comp < 0 && !node->left) {
|
||||
node->left = new_tree_node(key);
|
||||
return node->left;
|
||||
} else if (comp > 0 && node->right) {
|
||||
node = node->right;
|
||||
} else if (comp > 0 && !node->right) {
|
||||
node->right = new_tree_node(key);
|
||||
return node->right;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
void* tfind(const void* key, void* const* rootp, int (*comparator)(const void*, const void*))
|
||||
{
|
||||
if (!rootp)
|
||||
return nullptr;
|
||||
|
||||
auto node = static_cast<struct search_tree_node*>(*rootp);
|
||||
|
||||
while (node != nullptr) {
|
||||
auto comp = comparator(key, node->key);
|
||||
|
||||
if (comp < 0)
|
||||
node = node->left;
|
||||
else if (comp > 0)
|
||||
node = node->right;
|
||||
else
|
||||
return node;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue