finish writing and prepare to fix bugs

This commit is contained in:
2024-03-26 12:53:48 +00:00
parent 237d44c3da
commit 8f169ca426
3 changed files with 73 additions and 16 deletions

View File

@ -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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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\
&& 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)

View File

@ -243,7 +243,7 @@ class map {
successor->color = color_of_node;
if (parent_of_successor == node) {
successor->left = left_of_node;
successor->right = right_of_node;
successor->right = node;
successor->SetChildrensParent();
successor->parent = parent_of_node;
path_of_node = successor;
@ -264,8 +264,8 @@ class map {
}
}
void DeleteFixUp(RedBlackTreeNodeType *&tree_root) {
assert(this->left == nullptr && this->right == nullptr);
assert(this->color == RedBlackTreeColorType::BLACK);
if (this == tree_root) return;
RedBlackTreeNodeType *sibling = GetSibling();
assert(sibling != nullptr);
if (sibling->color == RedBlackTreeColorType::RED) {
@ -294,8 +294,6 @@ class map {
(distant_nephew == nullptr ||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
// Case 2
assert(close_nephew == nullptr);
assert(distant_nephew == nullptr);
sibling->color = RedBlackTreeColorType::RED;
this->parent->color = RedBlackTreeColorType::BLACK;
return;
@ -305,8 +303,6 @@ class map {
(distant_nephew == nullptr ||
distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::BLACK)) {
// Case 3
assert(close_nephew == nullptr);
assert(distant_nephew == nullptr);
sibling->color = RedBlackTreeColorType::RED;
this->parent->DeleteFixUp(tree_root);
return;
@ -328,13 +324,11 @@ class map {
assert(distant_nephew != nullptr && distant_nephew->color == RedBlackTreeColorType::RED);
// Then it must be Case 5
if (this == parent->left) {
sibling->color = parent->color;
parent->color = RedBlackTreeColorType::BLACK;
std::swap(sibling->color, parent->color);
distant_nephew->color = RedBlackTreeColorType::BLACK;
parent->RotateLeft(tree_root);
} else {
sibling->color = parent->color;
parent->color = RedBlackTreeColorType::BLACK;
std::swap(sibling->color, parent->color);
distant_nephew->color = RedBlackTreeColorType::BLACK;
parent->RotateRight(tree_root);
}
@ -351,7 +345,7 @@ class map {
RedBlackTreeNodeType *successor = pos->right;
while (successor->left != nullptr) successor = successor->left;
SwapNodeWithItsSuccessor(pos, successor, tree_root);
DeleteNode(successor, tree_root);
DeleteNode(pos, tree_root);
return;
}
if (pos->left == nullptr && pos->right == nullptr) {

View File

@ -1,6 +1,7 @@
#include <gtest/gtest.h>
#include <iostream>
#include <random>
#include <vector>
#include "map.hpp"
TEST(BasicTests, GTestItSelf) {
@ -62,3 +63,65 @@ TEST(BasicTests, MassiveOperatorInsert) {
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);
}
}