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\
|
||||
&& 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)
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user