引入红黑树近似查询

This commit is contained in:
2024-07-01 00:28:04 +08:00
parent f0abee1463
commit 9ce3503ec5
3 changed files with 176 additions and 11 deletions

View File

@@ -5,9 +5,19 @@ set(CMAKE_CXX_STANDARD 17)
include_directories(include) include_directories(include)
add_executable(DataStruct add_library(DataStruct
main.cpp
src/RedBlackTree.cpp src/RedBlackTree.cpp
src/HeapSort.cpp src/HeapSort.cpp
include/HeapSort.h 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 ()

View File

@@ -103,6 +103,8 @@ namespace ling {
/// 查找元素 /// 查找元素
Node *iterativeSearch(Node *x, T key) const; Node *iterativeSearch(Node *x, T key) const;
Node *findSearch(Node *x, T key) const;
/// 删除元素 /// 删除元素
void remove(Node *&root, Node *node); void remove(Node *&root, Node *node);
@@ -126,9 +128,12 @@ namespace ling {
/// 删除节点 /// 删除节点
void remove(T key); void remove(T key);
/// 查找节点 /// 查找元素
/// 区别于findSearch此方法会在没有匹配时返回接近的节点
Node *iterativeSearch(T key); Node *iterativeSearch(T key);
Node *findSearch(T key);
/// 根节点 /// 根节点
Node *getRoot() { Node *getRoot() {
return rootNode; return rootNode;
@@ -332,6 +337,24 @@ namespace ling {
template<typename T> template<typename T>
typename RedBlackTree<T>::Node *RedBlackTree<T>::iterativeSearch(RedBlackTree::Node *x, T key) const { typename RedBlackTree<T>::Node *RedBlackTree<T>::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 T>
typename RedBlackTree<T>::Node *RedBlackTree<T>::findSearch(RedBlackTree::Node *x, T key) const {
while ((x != nullptr) && equal(x->value, key) != EQUAL) { while ((x != nullptr) && equal(x->value, key) != EQUAL) {
if (equal(key, x->value) == SMALL) { if (equal(key, x->value) == SMALL) {
x = x->left; x = x->left;
@@ -342,6 +365,11 @@ namespace ling {
return x; return x;
} }
template<typename T>
typename RedBlackTree<T>::Node *RedBlackTree<T>::findSearch(T key) {
return findSearch(rootNode, key);
}
template<typename T> template<typename T>
typename RedBlackTree<T>::Node *RedBlackTree<T>::iterativeSearch(T key) { typename RedBlackTree<T>::Node *RedBlackTree<T>::iterativeSearch(T key) {
return iterativeSearch(rootNode, key); return iterativeSearch(rootNode, key);

143
main.cpp
View File

@@ -4,6 +4,7 @@
#include <random> #include <random>
#include <chrono> #include <chrono>
#include <iomanip> #include <iomanip>
#include <gtest/gtest.h>
class RedBlackTree : public ling::RedBlackTree<int> { class RedBlackTree : public ling::RedBlackTree<int> {
protected: 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() #define StartStating(name) auto name = std::chrono::high_resolution_clock::now()
@@ -27,7 +28,8 @@ auto duration = std::chrono::duration_cast<std::chrono::microseconds>(__ling_end
std::cout << text << ": " << std::fixed << std::setprecision(6) <<((double)duration.count() / 1000000) << " 秒(" << duration.count() <<" 微秒)" << std::endl;\ std::cout << text << ": " << std::fixed << std::setprecision(6) <<((double)duration.count() / 1000000) << " 秒(" << duration.count() <<" 微秒)" << std::endl;\
}while(false) }while(false)
int main() {
TEST(, ) {
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::mt19937 gen(rd());
@@ -45,11 +47,136 @@ int main() {
EndStating(start, "排序耗时"); EndStating(start, "排序耗时");
for (int i = 1; i < list.size(); i++) { for (int i = 1; i < list.size(); i++) {
if (list[i] < list[i - 1]) { ASSERT_TRUE(list[i] >= list[i - 1]);
std::cout << "错误!" << std::endl;
return -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);
} }