引入红黑树近似查询
This commit is contained in:
@@ -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 ()
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
139
main.cpp
139
main.cpp
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user