finish writing and prepare to fix bugs
This commit is contained in:
@ -13,21 +13,21 @@ add_executable(mp_five_mem ${CMAKE_CURRENT_SOURCE_DIR}/data/five.memcheck/code.c
|
|||||||
add_test(NAME mp_one COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_one >/tmp/one_out.txt\
|
add_test(NAME mp_one COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_one >/tmp/one_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_out.txt>/tmp/one_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_out.txt>/tmp/one_diff.txt")
|
||||||
add_test(NAME mp_one_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_one_mem >/tmp/one_mem_out.txt\
|
add_test(NAME mp_one_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_one_mem >/tmp/one_mem_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one/answer.txt /tmp/one_mem_out.txt>/tmp/one_mem_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/one.memcheck/answer.txt /tmp/one_mem_out.txt>/tmp/one_mem_diff.txt")
|
||||||
add_test(NAME mp_two COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_two >/tmp/two_out.txt\
|
add_test(NAME mp_two COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_two >/tmp/two_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two/answer.txt /tmp/two_out.txt>/tmp/two_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two/answer.txt /tmp/two_out.txt>/tmp/two_diff.txt")
|
||||||
add_test(NAME mp_two_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_two_mem >/tmp/two_mem_out.txt\
|
add_test(NAME mp_two_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_two_mem >/tmp/two_mem_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two/answer.txt /tmp/two_mem_out.txt>/tmp/two_mem_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/two.memcheck/answer.txt /tmp/two_mem_out.txt>/tmp/two_mem_diff.txt")
|
||||||
add_test(NAME mp_three COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_three >/tmp/three_out.txt\
|
add_test(NAME mp_three COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_three >/tmp/three_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three/answer.txt /tmp/three_out.txt>/tmp/three_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three/answer.txt /tmp/three_out.txt>/tmp/three_diff.txt")
|
||||||
add_test(NAME mp_three_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_three_mem >/tmp/three_mem_out.txt\
|
add_test(NAME mp_three_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_three_mem >/tmp/three_mem_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three/answer.txt /tmp/three_mem_out.txt>/tmp/three_mem_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/three.memcheck/answer.txt /tmp/three_mem_out.txt>/tmp/three_mem_diff.txt")
|
||||||
add_test(NAME mp_four COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_four >/tmp/four_out.txt\
|
add_test(NAME mp_four COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_four >/tmp/four_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four/answer.txt /tmp/four_out.txt>/tmp/four_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four/answer.txt /tmp/four_out.txt>/tmp/four_diff.txt")
|
||||||
add_test(NAME mp_four_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_four_mem >/tmp/four_mem_out.txt\
|
add_test(NAME mp_four_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_four_mem >/tmp/four_mem_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four/answer.txt /tmp/four_mem_out.txt>/tmp/four_mem_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/four.memcheck/answer.txt /tmp/four_mem_out.txt>/tmp/four_mem_diff.txt")
|
||||||
add_test(NAME mp_five COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five >/tmp/five_out.txt\
|
add_test(NAME mp_five COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five >/tmp/five_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_out.txt>/tmp/five_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_out.txt>/tmp/five_diff.txt")
|
||||||
add_test(NAME mp_five_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five_mem >/tmp/five_mem_out.txt\
|
add_test(NAME mp_five_mem COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/mp_five_mem >/tmp/five_mem_out.txt\
|
||||||
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five/answer.txt /tmp/five_mem_out.txt>/tmp/five_mem_diff.txt")
|
&& diff -u ${CMAKE_CURRENT_SOURCE_DIR}/data/five.memcheck/answer.txt /tmp/five_mem_out.txt>/tmp/five_mem_diff.txt")
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
@ -243,7 +243,7 @@ class map {
|
|||||||
successor->color = color_of_node;
|
successor->color = color_of_node;
|
||||||
if (parent_of_successor == node) {
|
if (parent_of_successor == node) {
|
||||||
successor->left = left_of_node;
|
successor->left = left_of_node;
|
||||||
successor->right = right_of_node;
|
successor->right = node;
|
||||||
successor->SetChildrensParent();
|
successor->SetChildrensParent();
|
||||||
successor->parent = parent_of_node;
|
successor->parent = parent_of_node;
|
||||||
path_of_node = successor;
|
path_of_node = successor;
|
||||||
@ -264,8 +264,8 @@ class map {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
void DeleteFixUp(RedBlackTreeNodeType *&tree_root) {
|
void DeleteFixUp(RedBlackTreeNodeType *&tree_root) {
|
||||||
assert(this->left == nullptr && this->right == nullptr);
|
|
||||||
assert(this->color == RedBlackTreeColorType::BLACK);
|
assert(this->color == RedBlackTreeColorType::BLACK);
|
||||||
|
if (this == tree_root) return;
|
||||||
RedBlackTreeNodeType *sibling = GetSibling();
|
RedBlackTreeNodeType *sibling = GetSibling();
|
||||||
assert(sibling != nullptr);
|
assert(sibling != nullptr);
|
||||||
if (sibling->color == RedBlackTreeColorType::RED) {
|
if (sibling->color == RedBlackTreeColorType::RED) {
|
||||||
@ -294,8 +294,6 @@ class map {
|
|||||||
(distant_nephew == nullptr ||
|
(distant_nephew == nullptr ||
|
||||||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
|
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
|
||||||
// Case 2
|
// Case 2
|
||||||
assert(close_nephew == nullptr);
|
|
||||||
assert(distant_nephew == nullptr);
|
|
||||||
sibling->color = RedBlackTreeColorType::RED;
|
sibling->color = RedBlackTreeColorType::RED;
|
||||||
this->parent->color = RedBlackTreeColorType::BLACK;
|
this->parent->color = RedBlackTreeColorType::BLACK;
|
||||||
return;
|
return;
|
||||||
@ -305,8 +303,6 @@ class map {
|
|||||||
(distant_nephew == nullptr ||
|
(distant_nephew == nullptr ||
|
||||||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
|
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
|
||||||
// Case 3
|
// Case 3
|
||||||
assert(close_nephew == nullptr);
|
|
||||||
assert(distant_nephew == nullptr);
|
|
||||||
sibling->color = RedBlackTreeColorType::RED;
|
sibling->color = RedBlackTreeColorType::RED;
|
||||||
this->parent->DeleteFixUp(tree_root);
|
this->parent->DeleteFixUp(tree_root);
|
||||||
return;
|
return;
|
||||||
@ -328,13 +324,11 @@ class map {
|
|||||||
assert(distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::RED);
|
assert(distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::RED);
|
||||||
// Then it must be Case 5
|
// Then it must be Case 5
|
||||||
if (this == parent->left) {
|
if (this == parent->left) {
|
||||||
sibling->color = parent->color;
|
std::swap(sibling->color, parent->color);
|
||||||
parent->color = RedBlackTreeColorType::BLACK;
|
|
||||||
distant_nephew->color = RedBlackTreeColorType::BLACK;
|
distant_nephew->color = RedBlackTreeColorType::BLACK;
|
||||||
parent->RotateLeft(tree_root);
|
parent->RotateLeft(tree_root);
|
||||||
} else {
|
} else {
|
||||||
sibling->color = parent->color;
|
std::swap(sibling->color, parent->color);
|
||||||
parent->color = RedBlackTreeColorType::BLACK;
|
|
||||||
distant_nephew->color = RedBlackTreeColorType::BLACK;
|
distant_nephew->color = RedBlackTreeColorType::BLACK;
|
||||||
parent->RotateRight(tree_root);
|
parent->RotateRight(tree_root);
|
||||||
}
|
}
|
||||||
@ -351,7 +345,7 @@ class map {
|
|||||||
RedBlackTreeNodeType *successor = pos->right;
|
RedBlackTreeNodeType *successor = pos->right;
|
||||||
while (successor->left != nullptr) successor = successor->left;
|
while (successor->left != nullptr) successor = successor->left;
|
||||||
SwapNodeWithItsSuccessor(pos, successor, tree_root);
|
SwapNodeWithItsSuccessor(pos, successor, tree_root);
|
||||||
DeleteNode(successor, tree_root);
|
DeleteNode(pos, tree_root);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pos->left == nullptr && pos->right == nullptr) {
|
if (pos->left == nullptr && pos->right == nullptr) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <vector>
|
||||||
#include "map.hpp"
|
#include "map.hpp"
|
||||||
|
|
||||||
TEST(BasicTests, GTestItSelf) {
|
TEST(BasicTests, GTestItSelf) {
|
||||||
@ -61,4 +62,66 @@ TEST(BasicTests, MassiveOperatorInsert) {
|
|||||||
EXPECT_EQ(mp_it->first, st_it->first);
|
EXPECT_EQ(mp_it->first, st_it->first);
|
||||||
EXPECT_EQ(mp_it->second, st_it->second);
|
EXPECT_EQ(mp_it->second, st_it->second);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicTests, BasicOperationErase) {
|
||||||
|
sjtu::map<int, int> mp;
|
||||||
|
mp[1] = 2;
|
||||||
|
mp[3] = 4;
|
||||||
|
mp[5] = 7;
|
||||||
|
mp[9] = 11;
|
||||||
|
auto it = mp.find(3);
|
||||||
|
mp.erase(it);
|
||||||
|
EXPECT_EQ(mp.size(), 3);
|
||||||
|
it = mp.begin();
|
||||||
|
EXPECT_EQ(it->first, 1);
|
||||||
|
EXPECT_EQ(it->second, 2);
|
||||||
|
it++;
|
||||||
|
EXPECT_EQ(it->first, 5);
|
||||||
|
EXPECT_EQ(it->second, 7);
|
||||||
|
it++;
|
||||||
|
EXPECT_EQ(it->first, 9);
|
||||||
|
EXPECT_EQ(it->second, 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(BasicTests, MassiveOperationErase) {
|
||||||
|
std::mt19937 rnd(2333333);
|
||||||
|
sjtu::map<int, int> map;
|
||||||
|
std::map<int, int> standard_map;
|
||||||
|
int nodes = 7, range = 7;
|
||||||
|
for (int i = 0; i < nodes; ++i) {
|
||||||
|
int key = rnd() % range;
|
||||||
|
int value = rnd() % range;
|
||||||
|
map[key] = value;
|
||||||
|
standard_map[key] = value;
|
||||||
|
std::cerr << "inserting " << key << " " << value << "\n";
|
||||||
|
}
|
||||||
|
std::vector<int> keys;
|
||||||
|
for (auto items : standard_map) keys.push_back(items.first);
|
||||||
|
for (int i = 0; i < nodes / 2; ++i) {
|
||||||
|
int kid = rnd() % keys.size();
|
||||||
|
int key = keys[kid];
|
||||||
|
std::cerr << "erasing " << key << "\n";
|
||||||
|
map.erase(map.find(key));
|
||||||
|
standard_map.erase(key);
|
||||||
|
keys.erase(keys.begin() + kid);
|
||||||
|
#ifndef NDEBUG
|
||||||
|
EXPECT_TRUE(map.RedBlackTreeStructureCheck());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
auto mp_it = map.begin();
|
||||||
|
auto st_it = standard_map.begin();
|
||||||
|
EXPECT_EQ(map.size(), standard_map.size());
|
||||||
|
for (; mp_it != map.end(); mp_it++, st_it++) {
|
||||||
|
EXPECT_EQ(mp_it->first, st_it->first);
|
||||||
|
EXPECT_EQ(mp_it->second, st_it->second);
|
||||||
|
}
|
||||||
|
mp_it = map.end();
|
||||||
|
st_it = standard_map.end();
|
||||||
|
for (int i = 0; i < map.size(); ++i) {
|
||||||
|
mp_it--;
|
||||||
|
st_it--;
|
||||||
|
EXPECT_EQ(mp_it->first, st_it->first);
|
||||||
|
EXPECT_EQ(mp_it->second, st_it->second);
|
||||||
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user