From efe2e4a83be67e31effc93649660270b2d589371 Mon Sep 17 00:00:00 2001 From: Xu Shaohua Date: Sun, 3 Dec 2023 09:04:49 +0800 Subject: [PATCH] ds: Traverse btree --- ds/4.tree/CMakeLists.txt | 9 +++++- ds/4.tree/binary_tree.h | 7 +++++ ds/4.tree/binary_tree_test.c | 16 ++++++++++ ds/4.tree/linked_binary_tree.c | 57 +++++++++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 ds/4.tree/binary_tree_test.c diff --git a/ds/4.tree/CMakeLists.txt b/ds/4.tree/CMakeLists.txt index 665882e6..658cb7d5 100644 --- a/ds/4.tree/CMakeLists.txt +++ b/ds/4.tree/CMakeLists.txt @@ -2,4 +2,11 @@ add_library(linked-binary-tree-static STATIC linked_binary_tree.c binary_tree.h - ) \ No newline at end of file + ) + +add_executable(binary-tree-test + binary_tree_test.c +) +target_link_libraries(binary-tree-test + linked-binary-tree-static +) diff --git a/ds/4.tree/binary_tree.h b/ds/4.tree/binary_tree.h index eaa9d7e1..dcc1a8b3 100644 --- a/ds/4.tree/binary_tree.h +++ b/ds/4.tree/binary_tree.h @@ -45,6 +45,12 @@ extern size_t binary_tree_size(binary_tree_t* tree); */ extern bool binary_tree_is_empty(binary_tree_t* tree); +enum tree_traverse_mode { + kTraverseInOrder = 0, + kTraversePreOrder, + kTraversePostOrder, +}; + /** * Calls |apply| function for each node in binary tree. * @@ -53,6 +59,7 @@ extern bool binary_tree_is_empty(binary_tree_t* tree); * @param user_data */ extern void binary_tree_traverse(binary_tree_t* tree, + tree_traverse_mode mode, void (*apply)(void* value, void* user_data), void* user_data); diff --git a/ds/4.tree/binary_tree_test.c b/ds/4.tree/binary_tree_test.c new file mode 100644 index 00000000..dc72b138 --- /dev/null +++ b/ds/4.tree/binary_tree_test.c @@ -0,0 +1,16 @@ +// Copyright (c) 2023 Xu Shaohua . All rights reserved. +// Use of this source is governed by General Public License that can be +// found in the LICENSE file. + +#include + +#include "binary_tree.h" + +int main(void) { + binary_tree_t* tree = binary_tree_new(); + + binary_tree_free(tree); + tree = NULL; + + return 0; +} diff --git a/ds/4.tree/linked_binary_tree.c b/ds/4.tree/linked_binary_tree.c index cf7f3701..af3eb8ea 100644 --- a/ds/4.tree/linked_binary_tree.c +++ b/ds/4.tree/linked_binary_tree.c @@ -45,4 +45,59 @@ size_t binary_tree_size(binary_tree_t* tree) { bool binary_tree_is_empty(binary_tree_t* tree) { assert(tree != NULL); return tree->size > 0; -} \ No newline at end of file +} + +static void tree_node_traverse_in_order(tree_node_t* node, + void (*apply)(void* value, void* user_data), + void* user_data) { + if (node != NULL) { + tree_node_traverse_in_order(node->left, apply, user_data); + apply(node->value, user_data); + tree_node_traverse_in_order(node->right, apply, user_data); + } +} + +static void tree_node_traverse_pre_order(tree_node_t* node, + void (*apply)(void* value, void* user_data), + void* user_data) { + if (node != NULL) { + apply(node->value, user_data); + tree_node_traverse_pre_order(node->left, apply, user_data); + tree_node_traverse_pre_order(node->right, apply, user_data); + } +} + +static void tree_node_traverse_post_order(tree_node_t* node, + void (*apply)(void* value, void* user_data), + void* user_data) { + if (node != NULL) { + tree_node_traverse_post_order(node->left, apply, user_data); + tree_node_traverse_post_order(node->right, apply, user_data); + apply(node->value, user_data); + } +} + +void binary_tree_traverse(binary_tree_t* tree, + tree_traverse_mode mode, + void (*apply)(void* value, void* user_data), + void* user_data) { + assert(tree != NULL); + switch (mode) { + case kTraverseInOrder: { + tree_node_traverse_in_order(tree->root, apply, user_data); + break; + } + case kTraversePreOrder: { + tree_node_traverse_pre_order(tree->root, apply, user_data); + break; + } + case kTraversePostOrder: { + tree_node_traverse_post_order(tree->root, apply, user_data); + break; + } + default: { + fprintf(stderr, "Invalid traverse mode\n"); + assert(0); + } + } +}