From 9ce3503ec5c85c2d66bc6df682eab513a0c28dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A9=BB=E9=AD=82=E5=9C=A3=E4=BD=BF?= Date: Mon, 1 Jul 2024 00:28:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BC=95=E5=85=A5=E7=BA=A2=E9=BB=91=E6=A0=91?= =?UTF-8?q?=E8=BF=91=E4=BC=BC=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 14 +++- include/RedBlackTree.h | 30 ++++++++- main.cpp | 143 ++++++++++++++++++++++++++++++++++++++--- 3 files changed, 176 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a1226c2..4fcbfd9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,9 +5,19 @@ set(CMAKE_CXX_STANDARD 17) include_directories(include) -add_executable(DataStruct - main.cpp +add_library(DataStruct src/RedBlackTree.cpp src/HeapSort.cpp include/HeapSort.h ) + +if (DEFINED ENABLE_TEST) + add_executable(myTest + main.cpp + ) + enable_testing() + find_package(GTest REQUIRED) + target_link_libraries(myTest PRIVATE GTest::GTest GTest::Main DataStruct) + set(GTEST_LIB gtest gtest_main) + add_test(NAME myTest COMMAND myTest) +endif () diff --git a/include/RedBlackTree.h b/include/RedBlackTree.h index 4296d89..714a13b 100644 --- a/include/RedBlackTree.h +++ b/include/RedBlackTree.h @@ -103,6 +103,8 @@ namespace ling { /// 查找元素 Node *iterativeSearch(Node *x, T key) const; + Node *findSearch(Node *x, T key) const; + /// 删除元素 void remove(Node *&root, Node *node); @@ -126,9 +128,12 @@ namespace ling { /// 删除节点 void remove(T key); - /// 查找节点 + /// 查找元素 + /// 区别于findSearch,此方法会在没有匹配时返回接近的节点 Node *iterativeSearch(T key); + Node *findSearch(T key); + /// 根节点 Node *getRoot() { return rootNode; @@ -332,6 +337,24 @@ namespace ling { template typename RedBlackTree::Node *RedBlackTree::iterativeSearch(RedBlackTree::Node *x, T key) const { + Relation temp; + Node *closest = nullptr; + while (x != nullptr) { + temp = equal(x->value, key); + if (temp == EQUAL) + return x; + if (temp == SMALL) { + closest = x; + x = x->right; + } else { + x = x->left; + } + } + return closest; + } + + template + typename RedBlackTree::Node *RedBlackTree::findSearch(RedBlackTree::Node *x, T key) const { while ((x != nullptr) && equal(x->value, key) != EQUAL) { if (equal(key, x->value) == SMALL) { x = x->left; @@ -342,6 +365,11 @@ namespace ling { return x; } + template + typename RedBlackTree::Node *RedBlackTree::findSearch(T key) { + return findSearch(rootNode, key); + } + template typename RedBlackTree::Node *RedBlackTree::iterativeSearch(T key) { return iterativeSearch(rootNode, key); diff --git a/main.cpp b/main.cpp index 333509c..261b529 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include class RedBlackTree : public ling::RedBlackTree { protected: @@ -16,7 +17,7 @@ protected: } }; -#define DATA_SIZE 10000000 +#define DATA_SIZE 100000 //开始一个统计点 #define StartStating(name) auto name = std::chrono::high_resolution_clock::now() @@ -27,7 +28,8 @@ auto duration = std::chrono::duration_cast(__ling_end std::cout << text << ": " << std::fixed << std::setprecision(6) <<((double)duration.count() / 1000000) << " 秒(" << duration.count() <<" 微秒)" << std::endl;\ }while(false) -int main() { + +TEST(排序, 堆排序测试) { std::random_device rd; std::mt19937 gen(rd()); @@ -45,11 +47,136 @@ int main() { EndStating(start, "排序耗时"); for (int i = 1; i < list.size(); i++) { - if (list[i] < list[i - 1]) { - std::cout << "错误!" << std::endl; - return -1; - } + ASSERT_TRUE(list[i] >= list[i - 1]); } - - return 0; +} + +TEST(红黑树, 搜索测试) { + RedBlackTree tree; + tree.insert(5); + tree.insert(10); + tree.insert(15); + tree.insert(20); + tree.insert(25); + tree.insert(30); + tree.insert(33); + tree.insert(35); + tree.insert(40); + tree.insert(45); + tree.insert(50); + auto node = tree.iterativeSearch(1); + ASSERT_TRUE(node == nullptr); + node = tree.iterativeSearch(4); + ASSERT_TRUE(node == nullptr); + node = tree.iterativeSearch(5); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 5); + node = tree.iterativeSearch(6); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 5); + node = tree.iterativeSearch(7); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 5); + node = tree.iterativeSearch(8); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 5); + node = tree.iterativeSearch(9); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 5); + node = tree.iterativeSearch(10); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 10); + node = tree.iterativeSearch(11); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 10); + node = tree.iterativeSearch(12); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 10); + node = tree.iterativeSearch(13); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 10); + node = tree.iterativeSearch(14); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 10); + node = tree.iterativeSearch(15); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 15); + node = tree.iterativeSearch(16); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 15); + node = tree.iterativeSearch(17); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 15); + node = tree.iterativeSearch(18); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 15); + node = tree.iterativeSearch(19); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 15); + node = tree.iterativeSearch(20); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 20); + node = tree.iterativeSearch(21); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 20); + node = tree.iterativeSearch(22); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 20); + node = tree.iterativeSearch(23); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 20); + node = tree.iterativeSearch(24); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 20); + node = tree.iterativeSearch(25); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 25); + node = tree.iterativeSearch(26); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 25); + node = tree.iterativeSearch(27); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 25); + node = tree.iterativeSearch(28); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 25); + node = tree.iterativeSearch(29); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 25); + node = tree.iterativeSearch(30); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 30); + node = tree.iterativeSearch(31); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 30); + node = tree.iterativeSearch(32); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 30); + node = tree.iterativeSearch(33); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 33); + node = tree.iterativeSearch(34); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 33); + node = tree.iterativeSearch(35); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 35); + node = tree.iterativeSearch(44); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 40); + node = tree.iterativeSearch(45); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 45); + node = tree.iterativeSearch(46); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 45); + node = tree.iterativeSearch(49); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 45); + node = tree.iterativeSearch(50); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 50); + node = tree.iterativeSearch(1000); + ASSERT_FALSE(node == nullptr); + ASSERT_EQ(node->value, 50); }