Fix bugs of rb-tree. The bug is about searching element with key no-less-than

or no-greater-than given key.
master
Shuxin Yang 2014-08-14 11:49:33 -07:00
parent e912288905
commit 3e34a802c7
2 changed files with 98 additions and 19 deletions

View File

@ -8,6 +8,8 @@ using namespace std;
#define RN(v) {v + KEY_VAL_DELTA, v, RB_RED}
#define BN(v) {v + KEY_VAL_DELTA, v, RB_BLACK}
#define ARRAY_SIZE(o) (sizeof((o))/sizeof((o)[0]))
class RB_UNIT_TEST {
public:
// If come across a bug, turn on "dump_tree" to instruct the unit-tester
@ -23,6 +25,13 @@ public:
_save_fail_cnt = _fail_cnt;
}
RB_UNIT_TEST(int test_id, bool dump_tree = false):
_test_id(test_id), _dump_tree(dump_tree) {
fprintf(stdout, "Testing unit test %d ...", test_id);
_rbt = rbt_create();
_save_fail_cnt = _fail_cnt;
}
~RB_UNIT_TEST() {
if (_rbt)
rbt_destroy(_rbt);
@ -46,13 +55,39 @@ public:
return false;
}
bool Search(int key, intptr_t val, bool expect_ret_val = 1) {
bool BulkInsert(int* val_vect, int vect_len) {
for (int i = 0; i < vect_len; i++) {
if (!InsertHelper(val_vect[i], 1)) {
_fail_cnt ++;
return false;
}
}
return true;
}
bool Search(int key, intptr_t val, RBS_RESULT expect_ret_val = RBS_EXACT) {
if (SearchHelper(key, val, expect_ret_val))
return true;
_fail_cnt ++;
return false;
}
bool SearchLessEqu(int key, int le_key, RBS_RESULT expect_ret_val) {
if (SearchVariantHelper(key, le_key, true /*LE*/, expect_ret_val)) {
return true;
}
_fail_cnt ++;
return false;
}
bool SearchGreaterEqu(int key, int ge_key, RBS_RESULT expect_ret_val) {
if (SearchVariantHelper(key, ge_key, false /*GE*/, expect_ret_val)) {
return true;
}
_fail_cnt ++;
return false;
}
private:
bool DeleteHelper(int val, int expect_ret_val) {
if (!_rbt)
@ -72,7 +107,7 @@ private:
if (ret == expect_ret_val && rbt_verify(_rbt) && VerifyKeyVal())
return true;
fprintf(stdout, " fail to delete %d", val);
fprintf(stdout, " fail to delete %d;", val);
return false;
}
@ -94,11 +129,11 @@ private:
if (ret == expect_ret_val && rbt_verify(_rbt) && VerifyKeyVal())
return true;
fprintf(stdout, " fail to insert %d", key);
fprintf(stdout, " fail to insert %d;", key);
return false;
}
bool SearchHelper(int key, intptr_t val, bool expect_ret_val) {
bool SearchHelper(int key, intptr_t val, RBS_RESULT expect_ret_val) {
if (!_rbt)
return false;
@ -114,11 +149,44 @@ private:
if (_dump_tree)
Dump_Tree("after_search");
if (ret == expect_ret_val && val == tmpval && rbt_verify(_rbt))
bool succ = (ret == expect_ret_val && val == tmpval);
succ = succ || expect_ret_val == RBS_FAIL;
succ = succ && rbt_verify(_rbt);
if (succ)
return true;
fprintf(stdout, " fail to search %d", key);
fprintf(stdout, " fail to search %d;", key);
return false;
}
bool SearchVariantHelper(int key, int res_key,
bool le_variant, RBS_RESULT expect_ret_val) {
if (!_rbt)
return false;
if (_dump_tree)
Dump_Tree("before_search");
if (!rbt_verify(_rbt))
return false;
intptr_t res_val;
int res_key2;
RBS_RESULT ret = rbt_search_variant(_rbt, key, &res_key2, &res_val,
le_variant ? 1 : 0);
if (_dump_tree)
Dump_Tree("after_search");
bool succ = (ret == expect_ret_val) &&
(res_key2 == res_key) && (res_val == (KEY_VAL_DELTA + res_key));
succ = succ || (expect_ret_val == RBS_FAIL);
succ = succ && rbt_verify(_rbt);
if (succ)
return true;
fprintf(stdout, " fail to search %d;", key);
return false;
}
@ -170,7 +238,7 @@ unit_test() {
// test 8.
{
rb_valcolor_t nodes[] = { BN(1), RN(2) };
RB_UNIT_TEST ut(8, nodes, 2);
RB_UNIT_TEST ut(8, nodes, ARRAY_SIZE(nodes));
ut.Delete(1);
ut.Delete(2);
}
@ -190,7 +258,7 @@ unit_test() {
{
rb_valcolor_t nodes[] = { BN(11), RN(2), BN(14), BN(1), BN(7),
RN(15), RN(5), RN(8) };
RB_UNIT_TEST ut(1, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(1, nodes, ARRAY_SIZE(nodes));
ut.Insert(4);
}
@ -199,7 +267,7 @@ unit_test() {
{
rb_valcolor_t nodes[] = { BN(4), BN(2), RN(10), RN(1), BN(7),
BN(11), RN(6), RN(9) };
RB_UNIT_TEST ut(2, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(2, nodes, ARRAY_SIZE(nodes));
ut.Insert(8);
}
@ -213,7 +281,7 @@ unit_test() {
// test 1
{
rb_valcolor_t nodes[] = { BN(40), BN(20), BN(60), RN(10), RN(50), RN(70) };
RB_UNIT_TEST ut(1, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(1, nodes, ARRAY_SIZE(nodes));
ut.Delete(20);
}
@ -221,7 +289,7 @@ unit_test() {
{
rb_valcolor_t nodes[] = { BN(40), BN(20), BN(60), RN(10), RN(30),
RN(50), RN(70) };
RB_UNIT_TEST ut(2, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(2, nodes, ARRAY_SIZE(nodes));
ut.Delete(20);
}
@ -229,7 +297,7 @@ unit_test() {
{
rb_valcolor_t nodes[] = { BN(40), BN(20), BN(60), BN(10), BN(30),
BN(50), BN(70), RN(21) };
RB_UNIT_TEST ut(3, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(3, nodes, ARRAY_SIZE(nodes));
ut.Delete(20);
}
@ -238,7 +306,7 @@ unit_test() {
rb_valcolor_t nodes[] = { BN(8), RN(2), BN(10), BN(0), BN(4), BN(9),
BN(11), BN(-1), BN(1), BN(3), RN(6),
BN(5), BN(7) };
RB_UNIT_TEST ut(4, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(4, nodes, ARRAY_SIZE(nodes));
ut.Delete(2);
}
@ -251,14 +319,14 @@ unit_test() {
BN(-11), BN(-9), BN(9), BN(11),
BN(29), BN(31),
BN(89), BN(91), BN(109), BN(111) };
RB_UNIT_TEST ut(5, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(5, nodes, ARRAY_SIZE(nodes));
ut.Delete(20);
}
// test 6. For case 1' and 2'
{
rb_valcolor_t nodes[] = { BN(4), RN(2), BN(5), BN(1), BN(3) };
RB_UNIT_TEST ut(6, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(6, nodes, ARRAY_SIZE(nodes));
ut.Delete(5);
}
@ -266,14 +334,14 @@ unit_test() {
{
rb_valcolor_t nodes[] = { BN(6), BN(2), BN(8), BN(1), RN(4), BN(7),
BN(9), BN(3), BN(5) };
RB_UNIT_TEST ut(7, nodes, sizeof(nodes)/sizeof(nodes[0]));
RB_UNIT_TEST ut(7, nodes, ARRAY_SIZE(nodes));
ut.Delete(8);
}
// test 8.
{
rb_valcolor_t nodes[] = { BN(1), RN(2) };
RB_UNIT_TEST ut(8, nodes, 2);
RB_UNIT_TEST ut(8, nodes, ARRAY_SIZE(nodes));
ut.Delete(1);
ut.Delete(2);
}
@ -281,7 +349,7 @@ unit_test() {
// test 9.
{
rb_valcolor_t nodes[] = { BN(1) };
RB_UNIT_TEST ut(8, nodes, 1);
RB_UNIT_TEST ut(9, nodes, ARRAY_SIZE(nodes));
ut.Delete(1);
}
@ -292,6 +360,17 @@ unit_test() {
/////////////////////////////////////////////////////////////////////////
//
// test 100
{
int val[] = { 1, 2, 3, 5, 7, 8 };
RB_UNIT_TEST ut(100);
ut.BulkInsert(val, ARRAY_SIZE(val));
ut.SearchLessEqu(4, 3, RBS_LESS);
ut.SearchLessEqu(3, 3, RBS_EXACT);
ut.SearchGreaterEqu(6, 7, RBS_GREATER);
ut.SearchGreaterEqu(7, 7, RBS_EXACT);
}
return RB_UNIT_TEST::Get_Fail_Cnt() == 0;
};

View File

@ -337,7 +337,7 @@ rbt_search_variant(rb_tree_t* rbt, int key, int* res_key, intptr_t* res_value,
if (res != RBS_FAIL) {
if (res_key)
*res_key = res_elemt - nd_vect;
*res_key = res_elemt->key;
if (res_value)
*res_value = res_elemt->value;