此文承接:算法实战:亲自写红黑树之一-CSDN博客
目录
这里给出的代码是实际可以运行的代码。
运行环境:VS2022,控制台项目,64位。注意,VS的数据类型和UNix/Linux是不一样的,64位下long仍然是32位的,long long才是64位。
包含三个文件,一个辅助文件,主要是树形显示的代码,一个头文件,是红黑树代码,一个主文件,是测试代码,包含main函数。
树形显示的代码,没有这个很难调试。
- #include
- #include
- using namespace std;
-
-
- struct _cell
- {
- string value;
- };
- struct _record
- {
- vector<_cell > cells;
- };
- class Table
- {
- private:
- vector<_record > m_bodys;
-
- size_t _GetColCount(vector<_record > const& trs)
- {
- vector<_record >::const_iterator it;
- size_t maxcount = 0;
- for (it = trs.begin(); it != trs.end(); ++it)
- {
- if (it->cells.size() > maxcount)maxcount = it->cells.size();
- }
- return maxcount;
- }
- size_t GetActualColCount()
- {
- //这个值是定义的列的数目和每个行的列数目之最大者
- size_t maxcount = 0;
- if (_GetColCount(m_bodys) > maxcount)maxcount = _GetColCount(m_bodys);
- return maxcount;
- }
- public:
- //设置数据,行必须有效,但可随意跳过一些列
- void SetData(size_t lineindex, size_t colindex, string const& data)
- {
- if (lineindex >= m_bodys.size())m_bodys.resize(lineindex + 1);
- if (colindex >= m_bodys[lineindex].cells.size())m_bodys[lineindex].cells.resize(colindex + 1);
- m_bodys[lineindex].cells[colindex].value = data;
- }
- //计算输出长度
- size_t outputlen(string const& s)
- {
- return utf8outputlen(s.c_str());
- }
- //utf-8中文通常为3个字节,输出仍为两个字符宽度
- size_t utf8outputlen(char const* s)
- {
- char const* p = s;
- long count_ansi = 0;
- long count_other = 0;
- while (*p)
- {
- if (*p < 0)++count_other;
- else ++count_ansi;
-
- ++p;
- }
- return count_ansi + count_other * 2 / 3;
- }
- //head_tail_n==0显示全部,否则只显示前后head_tail_n
- string MakeTextTable(size_t head_tail_n = 0)
- {
- string ret;
- size_t i, j;
- size_t actualcount = this->GetActualColCount();
- vector<size_t > v_colmaxlen;//列的最大宽度
- v_colmaxlen.reserve(actualcount);
- for (i = 0; i < actualcount; ++i)
- {
- v_colmaxlen.push_back(0);
- for (j = 0; j < m_bodys.size(); ++j)
- {
- if (i < m_bodys[j].cells.size())
- {
- string data = m_bodys[j].cells[i].value;
- if (outputlen(data) > v_colmaxlen[i])v_colmaxlen[i] = outputlen(data);
- }
- }
- }
-
- ret = "";
- string str;
-
- ret += "\n";
- for (i = 0; i < actualcount; ++i)
- {
- str.assign(v_colmaxlen[i], '-');
- ret += str;
- ret += " ";
- }
- ret += "\n";
- bool first_skip = true;
- for (j = 0; j < m_bodys.size(); ++j)
- {
- if (head_tail_n > 0 && j >= head_tail_n && j < m_bodys.size() - head_tail_n)
- {
- if (first_skip)
- {
- first_skip = false;
- ret += "......\n";
- }
- else continue;
- }
- else
- {
- for (i = 0; i < m_bodys[j].cells.size(); ++i)
- {
- string data = m_bodys[j].cells[i].value;
- str.assign(v_colmaxlen[i] - outputlen(data), ' ');
- ret += data;
- ret += str;
-
- ret += " ";
- }
- ret += "\n";
- }
- }
- for (i = 0; i < actualcount; ++i)
- {
- str.assign(v_colmaxlen[i], '-');
- ret += str;
- ret += " ";
- }
- ret += "\n";
-
- return ret;
- }
- };
-
这个类本来很大的,我删掉了所有不相关代码,只保留了显示树形结构的代码。这个代码在此文有介绍:程序设计:控制台输出二叉树 二叉树的形象显示-CSDN博客
这个代码不算复杂,其中计算输出长的outputlen是有问题的,没有真正按照字符数计算,一般我们只用asccii字符,不用中文,一般不会有问题(除非混有\t\r\n之类的格式字符)。
这个代码是比较长的,后面会拆解分析主要代码。
- #pragma once
-
- #include "a.h"
- #include
-
- extern bool G_IS_DEBUG;
- #define thelog cout<
" : " - #define debug_log if(G_IS_DEBUG)thelog
- #define endi endl
- #define ende " [ERROR]"<
-
- typedef long long T_SHM_SIZE;
-
- #define ARRAY_CAPACITY 10000
-
- struct CDemoData
- {
- long long n = 0;
-
- //用于需要排序的场合
- bool operator < (CDemoData const& tmp)const { return n < tmp.n; }
- //某些场合也需要等于
- bool operator == (CDemoData const& tmp)const { return n == tmp.n; }
-
- friend ostream& operator << (ostream& o, CDemoData const& d)
- {
- return o << d.n;
- }
-
- //用于输出数据的场合
- string& toString(string& str)const
- {
- char buf[2048];
- sprintf_s(buf, 2048, "%lld", n);
- return str = buf;
- }
- };
- typedef CDemoData T_DATA;
- typedef less
T_COMP; -
- struct TREE_NODE
- {
- T_SHM_SIZE hParent;//-1:无,根节点;0-N,子节点,或指向下个空闲地址
- T_SHM_SIZE hLeft;//-1表示无子节点
- T_SHM_SIZE hRight;//-1表示无子节点
- //颜色
- bool bColorRed;//是否为红色
- //删除标志
- signed char deleted;//0:有效,1:删除
- T_DATA data;
-
- TREE_NODE() :hParent(-1), hLeft(-1), hRight(-1), bColorRed(true), deleted(0) {}
- TREE_NODE(T_SHM_SIZE parent, T_DATA const& tmp) :hParent(parent), hLeft(-1), hRight(-1), bColorRed(true), deleted(0), data(tmp) {}
- string& toString(string& str, void* = NULL)const
- {
- char buf[2048];
- string tmp;
- if (-1 == _me())strcpy(buf, "空节点");
- else sprintf_s(buf, 2048, "%8lld : %8lld %8lld %8lld %s %1d : %10s", _me(), hParent, hLeft, hRight, (bColorRed ? "R" : "B"), deleted, data.toString(tmp).c_str());
- return str = buf;
- }
- string toString2(bool left,bool bStruct)const
- {
- if (-1 == _me())return "空节点";
- char buf[2048];
- string ret;
- if (!bStruct)
- {
- sprintf_s(buf, 2048, "%lld%s%lld", _me(), (bColorRed ? "+" : "-"), data.n);
- if (left)
- {
- ret = "[";
- ret += buf;
- }
- else
- {
- ret = buf;
- ret += "]";
- }
- }
- else
- {
- sprintf_s(buf, 2048, "p%lld L%lld R%lld", hParent, hLeft, hRight);
- ret = buf;
- }
- return ret;
- }
- bool operator < (TREE_NODE const& tmp)const
- {
- T_COMP comp;
- return comp(data, tmp.data);
- }
-
- static TREE_NODE& at(T_SHM_SIZE n);
- T_SHM_SIZE _me()const;
- T_SHM_SIZE _begin()const
- {
- if (-1 == hLeft)return _me();
- return at(hLeft)._begin();
- }
- T_SHM_SIZE _end()const
- {
- if (-1 == hRight)return _me();
- return at(hRight)._end();
- }
- bool isRight()const
- {
- return -1 != hParent && _me() == at(hParent).hRight;
- }
- bool isLeft()const
- {
- return !isRight();
- }
- void _CopyWithoutData(TREE_NODE const& tmp)
- {
- hParent = tmp.hParent;
- hLeft = tmp.hLeft;
- hRight = tmp.hRight;
- bColorRed = tmp.bColorRed;
- deleted = tmp.deleted;
- }
- };
-
- class CRBTree
- {
- public:
- struct iterator
- {
- T_SHM_SIZE handle;
-
- iterator() :handle(-1) {}
- bool operator == (iterator const& tmp)const { return handle == tmp.handle; }
- bool operator != (iterator const& tmp)const { return !(*this == tmp); }
- T_DATA& operator * ()const
- {
- return TREE_NODE::at(handle).data;
- }
- T_DATA* operator -> ()const
- {
- return &(operator *());
- }
- iterator& operator ++ ()
- {
- if (-1 != TREE_NODE::at(handle).hRight)
- {//存在右子树,取右子树的begin
- handle = TREE_NODE::at(handle).hRight;
- handle = TREE_NODE::at(handle)._begin();
- }
- else if (-1 != TREE_NODE::at(handle).hParent)
- {//存在父节点
- if (TREE_NODE::at(handle).isRight())
- {//是父节点的右子树,向上找到是左子树的节点,取这个节点的父节点
- while ((handle = TREE_NODE::at(handle).hParent) != -1 && TREE_NODE::at(handle).isRight()) {}
- if (-1 != handle && !TREE_NODE::at(handle).isRight())handle = TREE_NODE::at(handle).hParent;
- }
- else
- {//是父节点的左子树,取父节点
- handle = TREE_NODE::at(handle).hParent;
- }
- }
- else
- {//根节点且没有右子树,结束
- handle = -1;
- }
- return *this;
- }
- iterator& operator -- ()
- {
- if (-1 != TREE_NODE::at(handle).hLeft)
- {//存在左子树,取左子树的end
- handle = TREE_NODE::at(handle).hLeft;
- handle = TREE_NODE::at(handle)._end();
- }
- else if (-1 != TREE_NODE::at(handle).hParent)
- {//存在父节点
- if (TREE_NODE::at(handle).isLeft())
- {//是父节点的左子树,向上找到是右子树的节点,取这个节点的父节点
- while ((handle = TREE_NODE::at(handle).hParent) != -1 && TREE_NODE::at(handle).isLeft()) {}
- if (-1 != handle && !TREE_NODE::at(handle).isLeft())handle = TREE_NODE::at(handle).hParent;
- }
- else
- {//是父节点的右子树,取父节点
- handle = TREE_NODE::at(handle).hParent;
- }
- }
- else
- {//根节点且没有右子树,结束
- handle = -1;
- }
- return *this;
- }
- };
- typedef iterator const_iterator;
- struct TREE_HEAD
- {
- T_SHM_SIZE hHead;
- T_SHM_SIZE size;
- T_SHM_SIZE free_head;//空闲地址头指针
-
- TREE_HEAD() :hHead(-1), size(0), free_head(-1) {}
-
- //用于输出数据的场合
- string& toString(string& str)const
- {
- char buf[2048];
- sprintf_s(buf, 2048, "head %lld size %lld", hHead, size);
- return str;
- }
- };
-
- struct T_SETARRAY
- {
- //新版数组头
- struct array_head
- {
- T_SHM_SIZE capacity;
- T_SHM_SIZE size;
- };
- array_head _array_head;
- array_head const* GetHead()const { return &_array_head; }
- T_SHM_SIZE capacity()const { return _array_head.capacity; }
- T_SHM_SIZE size()const { return _array_head.size; }
- T_SHM_SIZE Capacity()const { return _array_head.capacity; }
- T_SHM_SIZE Size()const { return _array_head.size; }
-
- struct HANDLE
- {
- T_SHM_SIZE handle;
- };
- bool Add(TREE_NODE const& data, HANDLE& h)
- {
- if (_array_head.size == _array_head.capacity)return false;
- else
- {
- h.handle = _array_head.size;
- TREE_NODE::at(h.handle) = data;
- ++_array_head.size;
- return true;
- }
- }
-
- };
- private:
- TREE_HEAD _tree_head;
- private:
- //insert时如果已经存在保存被覆盖的数据
- bool m_OldValueSeted;
- T_DATA m_OldValue;
- public:
- T_SETARRAY m_array;//内置数组对象,存储实际数据
- TREE_HEAD* tree_head = &_tree_head;//指向树的头
- CRBTree() :m_OldValueSeted(false)
- {
- m_array._array_head.capacity = ARRAY_CAPACITY;
- m_array._array_head.size = 0;
- }
- T_SHM_SIZE size()const { return tree_head->size; }
- T_SHM_SIZE capacity()const { return m_array.GetHead()->capacity; }
- const_iterator begin()const
- {
- const_iterator it;
- if (-1 == tree_head->hHead)it.handle = -1;
- else it.handle = TREE_NODE::at(tree_head->hHead)._begin();
- return it;
- }
- const_iterator end()const
- {
- const_iterator it;
- it.handle = -1;
- return it;
- }
-
- bool _check_handle(T_SHM_SIZE h)const
- {
- return h >= -1 && h < m_array.GetHead()->size;
- }
- bool _check_is_data_node(T_SHM_SIZE h)const
- {
- return h >= 0 && h < m_array.GetHead()->size;
- }
- //获取节点总数,包括自身
- T_SHM_SIZE _check_get_count(T_SHM_SIZE h)
- {
- //thelog << h << endi;
- T_SHM_SIZE n = 0;
- if (_check_is_data_node(h))
- {
- ++n;
- //thelog << h << " " << TREE_NODE::at(h).hLeft<<" "<< TREE_NODE::at(h).hRight << endi;
- n += _check_get_count(TREE_NODE::at(h).hLeft);
- n += _check_get_count(TREE_NODE::at(h).hRight);
- }
- else
- {
- //thelog << "NULL" << endi;
- }
- return n;
- }
- //树形显示,px为偏移量,左边元素数
- void _check_show_tree(Table& table, T_SHM_SIZE h, bool left = true, T_SHM_SIZE line = 0, T_SHM_SIZE px = 0)
- {
- //thelog << h << " " << line << " " << px << endi;
- if (!_check_is_data_node(h))
- {
- //thelog << "空" << endi;
- return;
- }
-
- T_SHM_SIZE leftCount = _check_get_count(TREE_NODE::at(h).hLeft);
- //thelog << "leftCount " << leftCount << endi;
- T_SHM_SIZE pos = px + leftCount;
- table.SetData(line * 2, pos, TREE_NODE::at(h).toString2(left, false));//设置自身数据
- table.SetData(line * 2 + 1, pos, TREE_NODE::at(h).toString2(left, true));//设置自身数据
- //thelog << "TREE_NODE::at(h).hLeft " << TREE_NODE::at(h).hLeft << endi;
- _check_show_tree(table, TREE_NODE::at(h).hLeft, true, line + 1, px);//处理左子项
- //thelog << "TREE_NODE::at(h).hRight " << TREE_NODE::at(h).hRight << endi;
- _check_show_tree(table, TREE_NODE::at(h).hRight, false, line + 1, pos + 1);//处理右子项
- }
- void debug()
- {
- if (G_IS_DEBUG)
- {
- Table table;
- _check_show_tree(table, tree_head->hHead);
- thelog << endl << table.MakeTextTable() << endi;
- }
- }
-
- //检查红黑树特征
- bool _check_rbtree()
- {
- if (-1 == tree_head->hHead)return true;
- if (TREE_NODE::at(tree_head->hHead).bColorRed)
- {
- thelog << "根节点不是黑色" << ende;
- return false;
- }
- T_SHM_SIZE count_black = -1;
- if (_check_rbtree_count(tree_head->hHead, count_black, 0, 0, false))
- {
- debug_log << "深度 " << count_black << endi;
- return true;
- }
- else
- {
- return false;
- }
- }
- bool _check_rbtree_count(T_SHM_SIZE h, T_SHM_SIZE& count_black, T_SHM_SIZE black, T_SHM_SIZE red, bool PisRed)
- {
- if (-1 == h)
- {
- if (-1 == count_black)
- {
- count_black = black;
- return true;
- }
- else
- {
- if (black != count_black || red > black)
- {
- thelog << "深度不正确 " << count_black << " " << black << " " << red << ende;
- return false;
- }
- return true;
- }
- }
- else
- {
- if (TREE_NODE::at(h).bColorRed)
- {
- if (PisRed)
- {
- thelog << "连续红节点 " << h << ende;
- return false;
- }
- return _check_rbtree_count(TREE_NODE::at(h).hLeft, count_black, black, red + 1,true)
- && _check_rbtree_count(TREE_NODE::at(h).hRight, count_black, black, red + 1,true);
- }
- else
- return _check_rbtree_count(TREE_NODE::at(h).hLeft, count_black, black + 1, red,false)
- && _check_rbtree_count(TREE_NODE::at(h).hRight, count_black, black + 1, red,false);
- }
- }
-
- //检查数据结构是否正确
- bool _check()const
- {
- debug_log << "检查树结构,如果检查过程中发生数据修改则检查可能会出错" << endi;
-
- {
- size_t count_data_array = 0;//数组中的有效数据个数
- T_SHM_SIZE h;
- for (h = 0; h < static_cast
(m_array.size()); ++h) - {
- if (!TREE_NODE::at(h).deleted)++count_data_array;
- }
- debug_log << "数组容量 " << m_array.capacity() << " 个数 " << m_array.size() << " 有效数据 " << count_data_array << endi;
- debug_log << "树结构容量 " << capacity() << " 个数 " << size() << endi;
- if (count_data_array != size())
- {
- thelog << "树结构大小与数组统计不符 " << size() << " " << count_data_array << ende;
- return false;
- }
- }
-
- T_SHM_SIZE max_handle = m_array.GetHead()->size - 1;//整个已分配空间的最大句柄
- size_t count_free = 0;//未用节点数(删除的)
- //获取自由节点数
- {
- if (!_check_handle(tree_head->free_head))
- {
- thelog << "free_head error " << tree_head->free_head << ende;
- return false;
- }
- T_SHM_SIZE h = tree_head->free_head;
- while (h >= 0)
- {
- if (!TREE_NODE::at(h).deleted)
- {
- thelog << "此节点未被标记为删除 " << h << ende;
- return false;
- }
- ++count_free;
- if (TREE_NODE::at(h).hParent<-1 || TREE_NODE::at(h).hParent>max_handle)
- {
- thelog << "TREE_NODE::at(h).hParent error " << TREE_NODE::at(h).hParent << ende;
- return false;
- }
- h = TREE_NODE::at(h).hParent;
- }
- }
- if (count_free != m_array.size() - size())
- {
- thelog << "删除链表总数不正确 " << count_free << " " << m_array.size() - size() << ende;
- return false;
- }
- debug_log << "删除链表节点总数 " << count_free << endi;
- size_t count_used = 0;//已用节点数
-
- //获取已用节点数
- {
- T_COMP comp;
- iterator it = begin();
- iterator it_old = end();
- while (it != end())
- {
- if (!_check_handle(it.handle))
- {
- thelog << "无效的节点 " << it.handle << ende;
- return false;
- }
- if (TREE_NODE::at(it.handle).deleted)
- {
- thelog << "此节点被标记为删除 " << it.handle << ende;
- return false;
- }
- if (it_old == it)
- {
- thelog << "指针循环 [" << it_old.handle << "][" << it.handle << "]" << ende;
- return false;
- }
- if (it_old != end() && !comp(*it_old, *it))
- {
- string str1, str2;
- thelog << "节点数据比较错误 [" << it_old->toString(str1) << "][" << it->toString(str2) << "]" << ende;
- return false;
- }
- ++count_used;
- it_old = it;
- ++it;
- }
- }
- if (count_used != static_cast<size_t>(tree_head->size))
- {
- thelog << "begin->end != size " << count_used << " " << tree_head->size << ende;
- return false;
- }
- if (count_used != size())
- {
- thelog << "遍历获得节点数不正确 " << count_used << " " << size() << ende;
- return false;
- }
-
- debug_log << "检查完成,没有错误" << endi;
- return true;
- }
- private:
- //替换数据(只在插入时使用)
- void _update(T_SHM_SIZE position, T_DATA const& tmp)
- {
- TREE_NODE::at(position).data = tmp;
- }
-
- //修改头指针指向 src 的改为指向des(除了旋转只在删除里用到)
- void _changeRoot(T_SHM_SIZE src, T_SHM_SIZE des)
- {
- TREE_NODE::at(des).hParent = TREE_NODE::at(src).hParent;
- if (TREE_NODE::at(des).hParent != -1)
- {
- //旋转后是左节点
- if (TREE_NODE::at(TREE_NODE::at(des).hParent).hLeft == src)
- TREE_NODE::at(TREE_NODE::at(des).hParent).hLeft = des;
- //旋转后是右节点
- else
- TREE_NODE::at(TREE_NODE::at(des).hParent).hRight = des;
- }
- else
- {
- tree_head->hHead = des;
- }
- }
-
- //右旋转
- void _RRotate(T_SHM_SIZE p)
- {
- debug_log << "右旋" << p << endi;
- //assert(p>=0&&p
size); -
- //DEBUG_LOG<<"当前位置"<
size <
- T_SHM_SIZE t_lchild = TREE_NODE::at(p).hLeft;
- TREE_NODE::at(p).hLeft = TREE_NODE::at(t_lchild).hRight;
-
- //右节点非空
- if (TREE_NODE::at(t_lchild).hRight != -1)
- TREE_NODE::at(TREE_NODE::at(t_lchild).hRight).hParent = p;
-
- //修改根节点父指针
- _changeRoot(p, t_lchild);
-
- TREE_NODE::at(p).hParent = t_lchild;
- TREE_NODE::at(t_lchild).hRight = p;
-
- }
-
- //左旋转
- void _LRotate(T_SHM_SIZE p)
- {
- debug_log << "左旋 " << p << endi;
-
- string tmp;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
-
- T_SHM_SIZE t_rchild = TREE_NODE::at(p).hRight;
- debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
-
- TREE_NODE::at(p).hRight = TREE_NODE::at(t_rchild).hLeft;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
-
- //右节点非空
- if (TREE_NODE::at(t_rchild).hLeft != -1)
- {
- TREE_NODE::at(TREE_NODE::at(t_rchild).hLeft).hParent = p;
- debug_log << "TREE_NODE::at(t_rchild).hLeft " << TREE_NODE::at(TREE_NODE::at(t_rchild).hLeft).toString(tmp) << endi;
- }
-
- //非根节点
- //DEBUG_LOG << "_LRotate t_rchild's parent" <
- //修改根节点父指针
- _changeRoot(p, t_rchild);
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
-
- TREE_NODE::at(p).hParent = t_rchild;
- TREE_NODE::at(t_rchild).hLeft = p;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
- }
-
- //交换颜色
- void _exchage_color(T_SHM_SIZE a, T_SHM_SIZE b)
- {
- bool tmp = TREE_NODE::at(a).bColorRed;
- TREE_NODE::at(a).bColorRed = TREE_NODE::at(b).bColorRed;
- TREE_NODE::at(b).bColorRed = tmp;
- }
- //是否是红色,-1当作黑色
- bool _isRed(T_SHM_SIZE h)
- {
- return h != -1 && TREE_NODE::at(h).bColorRed;
- }
-
- //插入的入口
- pair
bool> _insert(T_DATA const& tmp, T_COMP& comp) - {
-
- pair
bool> tmppair; - T_SHM_SIZE insert_position = -1;
- bool isLeft = true;//插入节点方向 默认左插入
- bool isInsert = false;
- if ((insert_position = __insert(tmp, tree_head->hHead, -1, isLeft, isInsert, comp)) >= 0)
- {
- tmppair.first.handle = insert_position;
- tmppair.second = isInsert;
- //DEBUG_LOG<<"插入节点"<
- }
- else
- {
- //插入失败或者空间已满
- thelog << "插入节点失败" << ende;
- tmppair.first.handle = -1;
- tmppair.second = false;
- }
-
- TREE_NODE::at(tree_head->hHead).bColorRed = false;//根节点始终是黑色,因为转置的时候不能改颜色,所以只能在最后改
-
- return tmppair;
-
- }
- //插入节点返回-1不成功,vp父节点的子节点(即试图在此处插入),_parent父节点,taller 判断插入数据后节点深度是否增加
- T_SHM_SIZE __insert(T_DATA const& tmp, T_SHM_SIZE vp, T_SHM_SIZE _parent, bool isLeft, bool& isInsert, T_COMP& comp)
- {
- T_SHM_SIZE insert_position = -1;
- if (vp == -1)
- {
- //此位置为空,在此处插入
- insert_position = tree_head->free_head;
- ___insert_new(tmp, insert_position, _parent, isLeft, isInsert);
- //DEBUG_LOG<<"insert_position="<
- }
- else
- {
- //此位置有数据,根据比较结果处理
- if (comp(TREE_NODE::at(vp).data, tmp))
- {
- //大,走右边
- if ((insert_position = __insert(tmp, TREE_NODE::at(vp).hRight, vp, false, isInsert, comp)) == -1)
- {
- return -1;
- }
- }
- else if (comp(tmp, TREE_NODE::at(vp).data))
- {
- //小,走左边
- if ((insert_position = __insert(tmp, TREE_NODE::at(vp).hLeft, vp, true, isInsert, comp)) == -1)
- {
- return -1;
- }
- }
- else
- {
- //相等,更新数据
- //thelog<<"插入数据已经存在"<
- m_OldValue = TREE_NODE::at(vp).data;//保存被覆盖的值
- m_OldValueSeted = true;//设置被覆盖的对象有效
- _update(vp, tmp);
- return vp;
- }
- }
- return insert_position;
- }
- //插入新节点,position为新节点的位置,来自空闲列表,parent为父节点的位置
- void ___insert_new(T_DATA const& data, T_SHM_SIZE& position, T_SHM_SIZE parent, bool isLeft, bool& isInsert)
- {
- if (position < 0)
- {
- //没有空闲位置,需要动态扩展长度
- if (m_array.Capacity() > m_array.Size())
- {
- TREE_NODE tmp;
- typename T_SETARRAY::HANDLE h;
- if (!m_array.Add(tmp, h))
- {
- thelog << "扩展数组出错" << ende;
- isInsert = false;
- return;
- }
- else
- {
- //tree_head = m_array.GetUserHead();算法测试不用
- position = h.handle;
- }
- }
- else
- {
- thelog << "空间已满,请申请更大空间!!!!!!!!!!!!!!!!!!" << ende;
- isInsert = false;
- return;
- }
- }
- else
- {
- //thelog<<"exist position="<
- }
- tree_head->free_head = TREE_NODE::at(position).hParent;//空闲队列用hParent指向下一个
- //char buf[256];
- //sprintf(buf,"%ld %p",position,&TREE_NODE::at(position));
- //thelog<
- new(&TREE_NODE::at(position)) TREE_NODE(parent, data);
- //DEBUG_LOG<
- TREE_NODE::at(position).deleted = 0;
- if (parent == -1)
- {
- //没有父节点,空树
- tree_head->hHead = position;
- TREE_NODE::at(position).bColorRed = false;//根节点为黑色
- }
- else
- {
- //修改父节点
- //DEBUG_LOG<
- if (isLeft)
- {
- TREE_NODE::at(parent).hLeft = position;
- //DEBUG_LOG<
- }
- else
- {
- TREE_NODE::at(parent).hRight = position;
- //DEBUG_LOG<
- }
- //平衡处理
- _RB_insert_Balance(position);
- }
- isInsert = true;
- //DEBUG_LOG<<"新增节点"<
- ++tree_head->size;
- if (tree_head->size % 200000 == 0)
- {
- thelog << "树结构新增数据" << tree_head->size << endi;
- }
- }
- void _RB_insert_Balance(T_SHM_SIZE x)
- {
- T_SHM_SIZE p = TREE_NODE::at(x).hParent;
- if (!_isRed(p))return;
-
- //连续红,需要调整
- bool isLeft = (x == TREE_NODE::at(p).hLeft);
- T_SHM_SIZE g = TREE_NODE::at(p).hParent;
- bool isL = (p == TREE_NODE::at(g).hLeft);
- T_SHM_SIZE u = (isL ? TREE_NODE::at(g).hRight : TREE_NODE::at(g).hLeft);
-
- if (_isRed(u))
- {
- //u为红只需要染色,然后递归
- TREE_NODE::at(p).bColorRed = false;
- TREE_NODE::at(u).bColorRed = false;
- TREE_NODE::at(g).bColorRed = true;
- _RB_insert_Balance(g);
- }
- else
- {
- if (isL)
- {
- if (isLeft)
- {//LL
- _RRotate(g);
- _exchage_color(p, g);
- }
- else
- {//LR
- _LRotate(p);
- _RRotate(g);
- _exchage_color(x, g);
- }
- }
- else
- {
- if (isLeft)
- {//RL
- _RRotate(p);
- _LRotate(g);
- _exchage_color(x, g);
- }
- else
- {//RR
- _LRotate(g);
- _exchage_color(p, g);
- }
- }
- }
- }
-
- //删除指定节点,将节点接入到空闲链表
- void __erase_node(T_SHM_SIZE position)
- {
- debug_log << "删除节点 " << position << endi;
- TREE_NODE::at(position).hParent = tree_head->free_head;
- tree_head->free_head = position;
- TREE_NODE::at(position).hLeft = -1;
- TREE_NODE::at(position).hRight = -1;
- TREE_NODE::at(position).deleted = 1;
-
- --tree_head->size;
- }
- //删除中间节点,将中间节点替换为左子树最大值(数据不动,改变树结构)
- bool __erase_change_middle(T_SHM_SIZE const position, bool& vLeft, bool& vRed, T_SHM_SIZE& u, bool& uRed, T_SHM_SIZE& p)
- {
- string tmp;
- T_SHM_SIZE new_position = TREE_NODE::at(position).hLeft;
- if (-1 != new_position)
- {
- while (-1 != TREE_NODE::at(new_position).hRight)
- {
- new_position = TREE_NODE::at(new_position).hRight;
- }
- }
- debug_log << "position " << position << " new_position " << new_position << endi;
- debug_log << "position " << position << TREE_NODE::at(position).toString(tmp) << endi;
- debug_log << "new_position " << new_position << TREE_NODE::at(new_position).toString(tmp) << endi;
-
- vLeft = false;
- vRed = TREE_NODE::at(new_position).bColorRed;
- p = TREE_NODE::at(new_position).hParent;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- if (p != position)
- {
- debug_log << "非直接对调 p " << TREE_NODE::at(p).toString(tmp) << ende;
- TREE_NODE t;
- t._CopyWithoutData(TREE_NODE::at(new_position));
- TREE_NODE::at(new_position)._CopyWithoutData(TREE_NODE::at(position));
- TREE_NODE::at(position)._CopyWithoutData(t);
-
- debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
- debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
-
- //注意,这里无法用isLeft来判断,因为父节点的hLeft和hRight是旧数据
- if (TREE_NODE::at(new_position).hParent != -1)
- {
- if (TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft == position)TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft = new_position;
- else TREE_NODE::at(TREE_NODE::at(new_position).hParent).hRight = new_position;
- }
- if (TREE_NODE::at(position).hParent != -1)
- {
- if (TREE_NODE::at(TREE_NODE::at(position).hParent).hLeft==new_position)TREE_NODE::at(TREE_NODE::at(position).hParent).hLeft = position;
- else TREE_NODE::at(TREE_NODE::at(position).hParent).hRight = position;
- }
-
- if (TREE_NODE::at(new_position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(new_position).hLeft).hParent = new_position;
- if (TREE_NODE::at(position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(position).hLeft).hParent = position;
-
- if (TREE_NODE::at(new_position).hRight != -1)TREE_NODE::at(TREE_NODE::at(new_position).hRight).hParent = new_position;
- if (TREE_NODE::at(position).hRight != -1)TREE_NODE::at(TREE_NODE::at(position).hRight).hParent = position;
- }
- else
- {
- debug_log << "直接对调 p " << TREE_NODE::at(p).toString(tmp) << endi;
- TREE_NODE t;
- t._CopyWithoutData(TREE_NODE::at(new_position));
- TREE_NODE::at(new_position)._CopyWithoutData(TREE_NODE::at(position));
- TREE_NODE::at(position)._CopyWithoutData(t);
- debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
- debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
-
- //注意,这里无法用isLeft来判断,因为父节点的hLeft和hRight是旧数据
- if (TREE_NODE::at(new_position).hParent != -1)
- {
- if (TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft == position)TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft = new_position;
- else TREE_NODE::at(TREE_NODE::at(new_position).hParent).hRight = new_position;
- }
- TREE_NODE::at(position).hParent = new_position;
-
- TREE_NODE::at(new_position).hLeft=position;
- if (TREE_NODE::at(position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(position).hLeft).hParent = position;
-
- if (TREE_NODE::at(new_position).hRight != -1)TREE_NODE::at(TREE_NODE::at(new_position).hRight).hParent = new_position;
- if (TREE_NODE::at(position).hRight != -1)TREE_NODE::at(TREE_NODE::at(position).hRight).hParent = position;
- }
-
- //如果是根节点
- if (-1 == TREE_NODE::at(new_position).hParent)
- {
- TREE_NODE::at(new_position).bColorRed = false;
- tree_head->hHead = new_position;
- }
- debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
- debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
- debug();
-
- return true;
- }
-
- //删除时做平衡,u可能是空节点
- bool _RB_erase_Balance(T_SHM_SIZE p, T_SHM_SIZE u)
- {
- if (-1 == p)
- {
- debug_log << "已经到顶,结束" << endi;
- return true;
- }
-
- string tmp;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- if (u != -1)debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
- else debug_log << "u -1" << endi;
-
- bool isL = (u == TREE_NODE::at(p).hRight);//兄弟节点是否是左节点
- T_SHM_SIZE s = (isL ? TREE_NODE::at(p).hLeft : TREE_NODE::at(p).hRight);
- T_SHM_SIZE r = -1;//s的红色子节点
- bool is_rL;//s的红色子节点是否是左节点
- debug_log << "平衡:p " << p << " u " << u << " s " << s << " TREE_NODE::at(s).hRight " << TREE_NODE::at(s).hRight << endi;
- if (TREE_NODE::at(s).hRight != -1 && TREE_NODE::at(TREE_NODE::at(s).hRight).bColorRed)
- {
- r = TREE_NODE::at(s).hRight;
- is_rL = false;
- }
- else if (TREE_NODE::at(s).hLeft != -1 && TREE_NODE::at(TREE_NODE::at(s).hLeft).bColorRed)
- {
- r = TREE_NODE::at(s).hLeft;
- is_rL = true;
- }
- else
- {
- r = -1;
- is_rL = false;//无意义
- }
-
- debug_log << "p " << p << " u " << u << " s " << s << " r(-1表示双黑) " << r << endi;
- debug();
- if (-1 == r)
- {
- debug_log << "s子节点均为黑" << endi;
- if (TREE_NODE::at(p).bColorRed)
- {
- debug_log << "p为红,s必为黑 s改为红p改为黑 结束" << endi;//s子节点均为黑,p改为黑,所以s改为红是安全的,不会造成双红
- TREE_NODE::at(s).bColorRed = true;
- TREE_NODE::at(p).bColorRed = false;
- debug();
- }
- else
- {
- debug_log << "p为黑" << endi;
- if (!TREE_NODE::at(s).bColorRed)
- {
- debug_log << "s为黑 s改为红平衡下层并向上递归" << endi;//p的左右分支均少1,所以p成为新的双黑节点
- //置s为红,p为新的u,递归
- TREE_NODE::at(s).bColorRed = true;
- debug();
- return _RB_erase_Balance(TREE_NODE::at(p).hParent, p);
- }
- else
- {
- debug_log << "s为红 " << TREE_NODE::at(s).toString(tmp) << endi;
- debug_log << TREE_NODE::at(TREE_NODE::at(s).hParent).toString(tmp) << endi;
- if (TREE_NODE::at(s).isLeft())
- {
- debug_log << "s为左 " << s << endi;
- //右旋p
- _RRotate(p);
- }
- else
- {
- debug_log << "s为右" << endi;
- _LRotate(p);
- }
- //p和s变色
- TREE_NODE::at(s).bColorRed = false;
- TREE_NODE::at(p).bColorRed = true;
- debug();
- //此时深度情况不变,但p变成了红,重新对p和u做平衡处理
- return _RB_erase_Balance(p, u);
- }
- }
- }
- else
- {
- if (isL && is_rL)
- {
- debug_log << "LL" << ende;
- TREE_NODE::at(r).bColorRed = TREE_NODE::at(s).bColorRed;
- TREE_NODE::at(s).bColorRed = TREE_NODE::at(p).bColorRed;
- _RRotate(p);
- TREE_NODE::at(p).bColorRed = false;
- }
- else if (isL && !is_rL)
- {
- debug_log << "LR" << endi;
-
- debug();
-
- TREE_NODE::at(r).bColorRed = TREE_NODE::at(p).bColorRed;
- debug();
- _LRotate(s);
- debug();
- _RRotate(p);
- debug();
- TREE_NODE::at(p).bColorRed = false;
-
- debug();
- }
- else if (!isL && is_rL)
- {
- debug_log << "RL------------------------" << endi;
- debug();
- TREE_NODE::at(r).bColorRed = TREE_NODE::at(p).bColorRed;
- debug();
- _RRotate(s);
- debug();
- string tmp;
- debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- debug_log << "s " << TREE_NODE::at(p).toString(tmp) << endi;
- _LRotate(p);
- debug();
- TREE_NODE::at(p).bColorRed = false;
- debug();
- }
- else if (!isL && !is_rL)
- {
- debug_log << "RR" << endi;
- TREE_NODE::at(r).bColorRed = TREE_NODE::at(s).bColorRed;
- TREE_NODE::at(s).bColorRed = TREE_NODE::at(p).bColorRed;
- _LRotate(p);
- TREE_NODE::at(p).bColorRed = false;
- }
- else
- {
- thelog << "非预期的状态" << ende;
- return false;
- }
- }
-
- return true;
- }
-
- //删除
- bool _erase(T_SHM_SIZE position)
- {
- string report;
- //DEBUG_LOG<<"开始删除...."<
-
- bool vLeft;//删除的节点是左子节点
- bool vRed;//删除的节点是红色
- T_SHM_SIZE p = TREE_NODE::at(position).hParent;//父节点
- T_SHM_SIZE u;//替换节点
- bool uRed;//替换节点是红色(-1为黑色)
-
- if (TREE_NODE::at(position).hLeft != -1 && TREE_NODE::at(position).hRight != -1)
- {
- debug_log << "左右都存在,替换为左子树最大值" << endi;
- if (!__erase_change_middle(position, vLeft, vRed, u, uRed, p))return false;
- debug();
- return _erase(position);
- }
- else if (-1 == TREE_NODE::at(position).hLeft && -1 == TREE_NODE::at(position).hRight)
- {
- vLeft = TREE_NODE::at(position).isLeft();
- vRed = TREE_NODE::at(position).bColorRed;
- u = -1;
- uRed = false;
-
- if (-1 == p)
- {
- debug_log << "最后一个节点" << endi;
- tree_head->hHead = -1;
- vRed = true;//阻止后面继续处理,删除红色无需额外处理
- }
- else
- {
- debug_log << "叶子节点" << endi;
- if (TREE_NODE::at(position).isLeft())TREE_NODE::at(p).hLeft = -1;
- else TREE_NODE::at(p).hRight = -1;
- }
- }
- else
- {
- vLeft = TREE_NODE::at(position).isLeft();
- vRed = TREE_NODE::at(position).bColorRed;
- if (-1 != TREE_NODE::at(position).hLeft)
- {
- debug_log << "左子树存在" << endi;
- u = TREE_NODE::at(position).hLeft;
- }
- else
- {
- debug_log << "右子树存在" << endi;
- u = TREE_NODE::at(position).hRight;
- }
- if (-1 == p)
- {
- debug_log << "根节点" << endi;
- tree_head->hHead = u;
- }
- else
- {
- if (vLeft)TREE_NODE::at(p).hLeft = u;
- else TREE_NODE::at(p).hRight = u;
- }
- TREE_NODE::at(u).hParent = p;
- uRed = TREE_NODE::at(u).bColorRed;
- p = TREE_NODE::at(u).hParent;
- }
-
- bool ret = true;
- if (vRed)
- {
- debug_log << "删除红色节点,不用调整" << endi;
- //string tmp;
- //debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
- //debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- //debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
- //TREE_NODE::at(u).hParent = p;
- //if (vLeft)TREE_NODE::at(p).hLeft = u;
- //else TREE_NODE::at(p).hRight = u;
- //debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
- //debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
- //debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
- }
- else if (!vRed && uRed)
- {
- debug_log << "删除黑色节点,替换节点红色改为黑色" << endi;
- TREE_NODE::at(u).bColorRed = false;
- }
- else
- {
- debug_log << "删除双黑节点================================================" << endi;
- ret = _RB_erase_Balance(p, u);
- }
-
- debug();
- if (ret)__erase_node(position);
-
- if (-1 != tree_head->hHead)TREE_NODE::at(tree_head->hHead).bColorRed = false;
-
- return ret;
- }
- string show(T_SHM_SIZE position)
- {
- char buf[2048];
- string tmp;
- TREE_NODE::at(position).toString(tmp);
- sprintf_s(buf, 2048, "%lld : %s", position, tmp.c_str());
- return buf;
- }
- public:
- //如果second为false则已经存在,发生了覆盖,用GetOldValue获得被覆盖的值
- pair
bool > insert(T_DATA const& data) - {
- T_COMP comp;
- return insert(data, comp);
- }
- pair
bool > insert(T_DATA const& data, T_COMP& comp) - {
- m_OldValueSeted = false;//清除被覆盖对象的有效标志
-
- pair
bool> ret; -
- ret.first = end();
- ret.second = false;
- if (tree_head->free_head < 0 && m_array.Capacity() <= m_array.Size())
- {
- thelog << "超出容量限制" << ende;
- return ret;
- }
-
- try
- {
- ret = _insert(data, comp);
- }
- catch (exception& e)
- {
- thelog << e.what() << ende;
- }
- //thelog<<"insert ret "<
- return ret;
- }
- //返回被覆盖的值,如果最近的操作没有发生覆盖则false
- bool GetOldValue(T_DATA& ret)const
- {
- if (m_OldValueSeted)
- {
- ret = m_OldValue;
- return true;
- }
- else
- {
- return false;
- }
- }
- template<typename T_FIND >
- const_iterator find(T_FIND const& tmp)const
- {
- T_COMP comp;
- const_iterator it = lower_bound
(tmp); - if (it != end())
- {
- if (comp(*it, tmp) || comp(tmp, *it))return end();
- }
- return it;
- }
- const_iterator find(T_DATA const& tmp, T_COMP& comp)const
- {
- const_iterator it = lower_bound(tmp, comp);
- if (it != end())
- {
- if (comp(*it, tmp) || comp(tmp, *it))return end();
- }
- return it;
- }
- bool erase(const_iterator it)
- {
- T_COMP comp;
- return erase(it, comp);
- }
- //删除并指向下一个
- iterator& DeleteAndMoveNext(iterator& it)
- {
- if (end() == it)return it;
-
- iterator& ret = it;
- iterator tmp = ret;
- ++ret;
- erase(tmp);
- return ret;
- }
- bool erase(const_iterator it, T_COMP& comp)
- {
- if (it.handle < 0)return true;
- //DEBUG_LOG<<"要删除节点"<
- bool ret = _erase(it.handle);
- return ret;
- }
- bool erase(T_DATA const& data)
- {
- T_COMP comp;
- return erase(data, comp);
- }
- bool erase(T_DATA const& data, T_COMP& comp)
- {
- const_iterator it = find(data, comp);
- if (it.handle < 0)return true;
- return erase(it, comp);
- }
- //用全比较函数,实际是find的功能
- template<typename T_FIND >
- const_iterator lower_bound(T_FIND const& tmp)const
- {
- T_COMP comp;
- const_iterator it;
-
- T_SHM_SIZE hNode = tree_head->hHead;
- it.handle = -1;
- while (-1 != hNode)
- {
- if (comp(tmp, TREE_NODE::at(hNode).data))
- {
- it.handle = hNode;
- hNode = TREE_NODE::at(hNode).hLeft;
- }
- else if (comp(TREE_NODE::at(hNode).data, tmp))
- {
- hNode = TREE_NODE::at(hNode).hRight;
- }
- else
- {
- it.handle = hNode;
- break;
- }
- }
-
- return it;
- }
- //用部分比较函数(但必须是符合顺序的,否则结果不可预期)
- template<typename T_FIND, typename T_LESS_BOUND >
- const_iterator lower_bound(T_FIND const& tmp, T_LESS_BOUND comp)const
- {
- const_iterator it;
-
- T_SHM_SIZE hNode = tree_head->hHead;
- it.handle = -1;
- while (-1 != hNode)
- {
- if (comp(tmp, TREE_NODE::at(hNode).data))
- {
- it.handle = hNode;
- hNode = TREE_NODE::at(hNode).hLeft;
- }
- else if (comp(TREE_NODE::at(hNode).data, tmp))
- {
- hNode = TREE_NODE::at(hNode).hRight;
- }
- else
- {
- it.handle = hNode;
- hNode = TREE_NODE::at(hNode).hLeft;
- }
- }
-
- return it;
- }
- //用部分比较函数(但必须是符合顺序的,否则结果不可预期)
- template<typename T_FIND, typename T_LESS_BOUND >
- const_iterator upper_bound(T_FIND const& tmp, T_LESS_BOUND comp)const
- {
- const_iterator it;
-
- T_SHM_SIZE hNode = tree_head->hHead;
- it.handle = -1;
- while (-1 != hNode)
- {
- if (comp(tmp, TREE_NODE::at(hNode).data))
- {
- it.handle = hNode;
- hNode = TREE_NODE::at(hNode).hLeft;
- }
- else if (comp(TREE_NODE::at(hNode).data, tmp))
- {
- hNode = TREE_NODE::at(hNode).hRight;
- }
- else
- {
- hNode = TREE_NODE::at(hNode).hRight;
- }
- }
-
- return it;
- }
- //检查一个节点是否已经删除,必须是有效参数
- bool IsDeleted(T_SHM_SIZE handle)const
- {
- if (handle < 0 || handle >= m_array.capacity())return false;
- return TREE_NODE::at(handle).deleted;
- }
- };
- #include
- #include
-
- #include "rbtree.h"
-
- bool G_IS_DEBUG;
-
- TREE_NODE g_array[ARRAY_CAPACITY];
- TREE_NODE& TREE_NODE::at(T_SHM_SIZE n)
- {
- return g_array[n];
- }
- T_SHM_SIZE TREE_NODE::_me()const
- {
- return this - g_array;
- }
-
- //日志用格式
- string TimeToString_log(time_t const & t1)
- {
- if (0 == t1)return "";
-
- tm const * t2;
- char buf[256];
- t2 = localtime(&t1);
- sprintf(buf, "%02d-%02d %02d:%02d:%02d", t2->tm_mon + 1, t2->tm_mday, t2->tm_hour, t2->tm_min, t2->tm_sec);
- return buf;
- }
-
- bool test(int _seed, int count)
- {
- CRBTree rbtree;
- T_DATA a;
-
- srand(_seed);
- vector
datas; - for (T_SHM_SIZE i = 0; i < count; ++i)
- {
- datas.push_back(rand());
- }
-
- debug_log << rbtree.size() << " " << rbtree.capacity() << endi;
- for (T_SHM_SIZE v : datas)
- {
- a.n = v;
- debug_log << a.n << endi;
- rbtree.insert(a);
- }
- debug_log << rbtree.size() << " " << rbtree.capacity() << endi;
-
- rbtree._check();
- rbtree._check_rbtree();
- // CRBTree::const_iterator it = rbtree.begin();
- // for (; it != rbtree.end(); ++it)
- // {
- // string tmp1,tmp2;
- //thelog <<"h "<< it.handle << " 值:" << it->toString(tmp1) << " TREE_NODE:" << TREE_NODE::at(it.handle).toString(tmp2) << endi;
- // }
- Table table;
- rbtree._check_show_tree(table, rbtree.tree_head->hHead);
- debug_log << endl << table.MakeTextTable() << endi;
-
- bool ret = true;
- for (T_SHM_SIZE v : datas)
- {
- a.n = v;
- debug_log << a.n << endi;
- ret = rbtree.erase(a) && rbtree._check() && rbtree._check_rbtree();
- if (G_IS_DEBUG)
- {
- Table table;
- rbtree._check_show_tree(table, rbtree.tree_head->hHead);
- thelog << endl << table.MakeTextTable() << endi;
- }
- if (!ret)break;
- }
- //CRBTree::const_iterator it = rbtree.begin();
- //for (; it != rbtree.end(); ++it)
- //{
- // string tmp1, tmp2;
- // thelog << "h " << it.handle << " 值:" << it->toString(tmp1) << " TREE_NODE:" << TREE_NODE::at(it.handle).toString(tmp2) << endi;
- //}
- return ret;
- }
- int main()
- {
- G_IS_DEBUG = true;//大数据量测试时先设置为false,然后把后面循环的次数调大
-
- int count = 10;//每次测试的数据量,上限为 ARRAY_CAPACITY;
- for (int i = 0; i < 1; ++i)
- {
- if (!test(i, count))
- {
- G_IS_DEBUG = true;
- thelog << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endi;
- test(i, count);
- thelog << "失败 i= " << i << endi;
- return 1;
- }
- thelog << TimeToString_log(time(NULL)) << " " << i << endi;
- //break;
- }
- return 0;
- }
-
以上三个代码就是全部代码,建立新工程,保存辅助代码和红黑树代码,用测试代码替换主代码,然后编译运行应该是没问题的。
运行效果:

由于是打开调试执行的,有很多输出,每一次改变树结构都有树形显示。
最后结果:

注意删除最后一个节点时调试输出为“删除红色节点,不用调整”,但是根节点其实是黑色的。这是因为代码里的临时变量把最后一个节点指示为红色,防止后面执行调整代码。这里算是个小缺陷吧(本该使用一个独立变量来指示的)。
(这里是结束)