• 算法实战:亲自写红黑树之二 完整代码


            此文承接:算法实战:亲自写红黑树之一-CSDN博客

    目录

    一、项目结构

    二、辅助代码a.h

    三、红黑树代码rbtree.h

    四、测试代码main.cpp

    五、运行效果

    六、代码详解


    一、项目结构

            这里给出的代码是实际可以运行的代码。

            运行环境:VS2022,控制台项目,64位。注意,VS的数据类型和UNix/Linux是不一样的,64位下long仍然是32位的,long long才是64位。

            包含三个文件,一个辅助文件,主要是树形显示的代码,一个头文件,是红黑树代码,一个主文件,是测试代码,包含main函数。

    二、辅助代码a.h

             树形显示的代码,没有这个很难调试。

    1. #include
    2. #include
    3. using namespace std;
    4. struct _cell
    5. {
    6. string value;
    7. };
    8. struct _record
    9. {
    10. vector<_cell > cells;
    11. };
    12. class Table
    13. {
    14. private:
    15. vector<_record > m_bodys;
    16. size_t _GetColCount(vector<_record > const& trs)
    17. {
    18. vector<_record >::const_iterator it;
    19. size_t maxcount = 0;
    20. for (it = trs.begin(); it != trs.end(); ++it)
    21. {
    22. if (it->cells.size() > maxcount)maxcount = it->cells.size();
    23. }
    24. return maxcount;
    25. }
    26. size_t GetActualColCount()
    27. {
    28. //这个值是定义的列的数目和每个行的列数目之最大者
    29. size_t maxcount = 0;
    30. if (_GetColCount(m_bodys) > maxcount)maxcount = _GetColCount(m_bodys);
    31. return maxcount;
    32. }
    33. public:
    34. //设置数据,行必须有效,但可随意跳过一些列
    35. void SetData(size_t lineindex, size_t colindex, string const& data)
    36. {
    37. if (lineindex >= m_bodys.size())m_bodys.resize(lineindex + 1);
    38. if (colindex >= m_bodys[lineindex].cells.size())m_bodys[lineindex].cells.resize(colindex + 1);
    39. m_bodys[lineindex].cells[colindex].value = data;
    40. }
    41. //计算输出长度
    42. size_t outputlen(string const& s)
    43. {
    44. return utf8outputlen(s.c_str());
    45. }
    46. //utf-8中文通常为3个字节,输出仍为两个字符宽度
    47. size_t utf8outputlen(char const* s)
    48. {
    49. char const* p = s;
    50. long count_ansi = 0;
    51. long count_other = 0;
    52. while (*p)
    53. {
    54. if (*p < 0)++count_other;
    55. else ++count_ansi;
    56. ++p;
    57. }
    58. return count_ansi + count_other * 2 / 3;
    59. }
    60. //head_tail_n==0显示全部,否则只显示前后head_tail_n
    61. string MakeTextTable(size_t head_tail_n = 0)
    62. {
    63. string ret;
    64. size_t i, j;
    65. size_t actualcount = this->GetActualColCount();
    66. vector<size_t > v_colmaxlen;//列的最大宽度
    67. v_colmaxlen.reserve(actualcount);
    68. for (i = 0; i < actualcount; ++i)
    69. {
    70. v_colmaxlen.push_back(0);
    71. for (j = 0; j < m_bodys.size(); ++j)
    72. {
    73. if (i < m_bodys[j].cells.size())
    74. {
    75. string data = m_bodys[j].cells[i].value;
    76. if (outputlen(data) > v_colmaxlen[i])v_colmaxlen[i] = outputlen(data);
    77. }
    78. }
    79. }
    80. ret = "";
    81. string str;
    82. ret += "\n";
    83. for (i = 0; i < actualcount; ++i)
    84. {
    85. str.assign(v_colmaxlen[i], '-');
    86. ret += str;
    87. ret += " ";
    88. }
    89. ret += "\n";
    90. bool first_skip = true;
    91. for (j = 0; j < m_bodys.size(); ++j)
    92. {
    93. if (head_tail_n > 0 && j >= head_tail_n && j < m_bodys.size() - head_tail_n)
    94. {
    95. if (first_skip)
    96. {
    97. first_skip = false;
    98. ret += "......\n";
    99. }
    100. else continue;
    101. }
    102. else
    103. {
    104. for (i = 0; i < m_bodys[j].cells.size(); ++i)
    105. {
    106. string data = m_bodys[j].cells[i].value;
    107. str.assign(v_colmaxlen[i] - outputlen(data), ' ');
    108. ret += data;
    109. ret += str;
    110. ret += " ";
    111. }
    112. ret += "\n";
    113. }
    114. }
    115. for (i = 0; i < actualcount; ++i)
    116. {
    117. str.assign(v_colmaxlen[i], '-');
    118. ret += str;
    119. ret += " ";
    120. }
    121. ret += "\n";
    122. return ret;
    123. }
    124. };

            这个类本来很大的,我删掉了所有不相关代码,只保留了显示树形结构的代码。这个代码在此文有介绍:程序设计:控制台输出二叉树 二叉树的形象显示-CSDN博客

            这个代码不算复杂,其中计算输出长的outputlen是有问题的,没有真正按照字符数计算,一般我们只用asccii字符,不用中文,一般不会有问题(除非混有\t\r\n之类的格式字符)。

    三、红黑树代码rbtree.h

            这个代码是比较长的,后面会拆解分析主要代码。

    1. #pragma once
    2. #include "a.h"
    3. #include
    4. extern bool G_IS_DEBUG;
    5. #define thelog cout<" : "
    6. #define debug_log if(G_IS_DEBUG)thelog
    7. #define endi endl
    8. #define ende " [ERROR]"<
    9. typedef long long T_SHM_SIZE;
    10. #define ARRAY_CAPACITY 10000
    11. struct CDemoData
    12. {
    13. long long n = 0;
    14. //用于需要排序的场合
    15. bool operator < (CDemoData const& tmp)const { return n < tmp.n; }
    16. //某些场合也需要等于
    17. bool operator == (CDemoData const& tmp)const { return n == tmp.n; }
    18. friend ostream& operator << (ostream& o, CDemoData const& d)
    19. {
    20. return o << d.n;
    21. }
    22. //用于输出数据的场合
    23. string& toString(string& str)const
    24. {
    25. char buf[2048];
    26. sprintf_s(buf, 2048, "%lld", n);
    27. return str = buf;
    28. }
    29. };
    30. typedef CDemoData T_DATA;
    31. typedef less T_COMP;
    32. struct TREE_NODE
    33. {
    34. T_SHM_SIZE hParent;//-1:无,根节点;0-N,子节点,或指向下个空闲地址
    35. T_SHM_SIZE hLeft;//-1表示无子节点
    36. T_SHM_SIZE hRight;//-1表示无子节点
    37. //颜色
    38. bool bColorRed;//是否为红色
    39. //删除标志
    40. signed char deleted;//0:有效,1:删除
    41. T_DATA data;
    42. TREE_NODE() :hParent(-1), hLeft(-1), hRight(-1), bColorRed(true), deleted(0) {}
    43. TREE_NODE(T_SHM_SIZE parent, T_DATA const& tmp) :hParent(parent), hLeft(-1), hRight(-1), bColorRed(true), deleted(0), data(tmp) {}
    44. string& toString(string& str, void* = NULL)const
    45. {
    46. char buf[2048];
    47. string tmp;
    48. if (-1 == _me())strcpy(buf, "空节点");
    49. 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());
    50. return str = buf;
    51. }
    52. string toString2(bool left,bool bStruct)const
    53. {
    54. if (-1 == _me())return "空节点";
    55. char buf[2048];
    56. string ret;
    57. if (!bStruct)
    58. {
    59. sprintf_s(buf, 2048, "%lld%s%lld", _me(), (bColorRed ? "+" : "-"), data.n);
    60. if (left)
    61. {
    62. ret = "[";
    63. ret += buf;
    64. }
    65. else
    66. {
    67. ret = buf;
    68. ret += "]";
    69. }
    70. }
    71. else
    72. {
    73. sprintf_s(buf, 2048, "p%lld L%lld R%lld", hParent, hLeft, hRight);
    74. ret = buf;
    75. }
    76. return ret;
    77. }
    78. bool operator < (TREE_NODE const& tmp)const
    79. {
    80. T_COMP comp;
    81. return comp(data, tmp.data);
    82. }
    83. static TREE_NODE& at(T_SHM_SIZE n);
    84. T_SHM_SIZE _me()const;
    85. T_SHM_SIZE _begin()const
    86. {
    87. if (-1 == hLeft)return _me();
    88. return at(hLeft)._begin();
    89. }
    90. T_SHM_SIZE _end()const
    91. {
    92. if (-1 == hRight)return _me();
    93. return at(hRight)._end();
    94. }
    95. bool isRight()const
    96. {
    97. return -1 != hParent && _me() == at(hParent).hRight;
    98. }
    99. bool isLeft()const
    100. {
    101. return !isRight();
    102. }
    103. void _CopyWithoutData(TREE_NODE const& tmp)
    104. {
    105. hParent = tmp.hParent;
    106. hLeft = tmp.hLeft;
    107. hRight = tmp.hRight;
    108. bColorRed = tmp.bColorRed;
    109. deleted = tmp.deleted;
    110. }
    111. };
    112. class CRBTree
    113. {
    114. public:
    115. struct iterator
    116. {
    117. T_SHM_SIZE handle;
    118. iterator() :handle(-1) {}
    119. bool operator == (iterator const& tmp)const { return handle == tmp.handle; }
    120. bool operator != (iterator const& tmp)const { return !(*this == tmp); }
    121. T_DATA& operator * ()const
    122. {
    123. return TREE_NODE::at(handle).data;
    124. }
    125. T_DATA* operator -> ()const
    126. {
    127. return &(operator *());
    128. }
    129. iterator& operator ++ ()
    130. {
    131. if (-1 != TREE_NODE::at(handle).hRight)
    132. {//存在右子树,取右子树的begin
    133. handle = TREE_NODE::at(handle).hRight;
    134. handle = TREE_NODE::at(handle)._begin();
    135. }
    136. else if (-1 != TREE_NODE::at(handle).hParent)
    137. {//存在父节点
    138. if (TREE_NODE::at(handle).isRight())
    139. {//是父节点的右子树,向上找到是左子树的节点,取这个节点的父节点
    140. while ((handle = TREE_NODE::at(handle).hParent) != -1 && TREE_NODE::at(handle).isRight()) {}
    141. if (-1 != handle && !TREE_NODE::at(handle).isRight())handle = TREE_NODE::at(handle).hParent;
    142. }
    143. else
    144. {//是父节点的左子树,取父节点
    145. handle = TREE_NODE::at(handle).hParent;
    146. }
    147. }
    148. else
    149. {//根节点且没有右子树,结束
    150. handle = -1;
    151. }
    152. return *this;
    153. }
    154. iterator& operator -- ()
    155. {
    156. if (-1 != TREE_NODE::at(handle).hLeft)
    157. {//存在左子树,取左子树的end
    158. handle = TREE_NODE::at(handle).hLeft;
    159. handle = TREE_NODE::at(handle)._end();
    160. }
    161. else if (-1 != TREE_NODE::at(handle).hParent)
    162. {//存在父节点
    163. if (TREE_NODE::at(handle).isLeft())
    164. {//是父节点的左子树,向上找到是右子树的节点,取这个节点的父节点
    165. while ((handle = TREE_NODE::at(handle).hParent) != -1 && TREE_NODE::at(handle).isLeft()) {}
    166. if (-1 != handle && !TREE_NODE::at(handle).isLeft())handle = TREE_NODE::at(handle).hParent;
    167. }
    168. else
    169. {//是父节点的右子树,取父节点
    170. handle = TREE_NODE::at(handle).hParent;
    171. }
    172. }
    173. else
    174. {//根节点且没有右子树,结束
    175. handle = -1;
    176. }
    177. return *this;
    178. }
    179. };
    180. typedef iterator const_iterator;
    181. struct TREE_HEAD
    182. {
    183. T_SHM_SIZE hHead;
    184. T_SHM_SIZE size;
    185. T_SHM_SIZE free_head;//空闲地址头指针
    186. TREE_HEAD() :hHead(-1), size(0), free_head(-1) {}
    187. //用于输出数据的场合
    188. string& toString(string& str)const
    189. {
    190. char buf[2048];
    191. sprintf_s(buf, 2048, "head %lld size %lld", hHead, size);
    192. return str;
    193. }
    194. };
    195. struct T_SETARRAY
    196. {
    197. //新版数组头
    198. struct array_head
    199. {
    200. T_SHM_SIZE capacity;
    201. T_SHM_SIZE size;
    202. };
    203. array_head _array_head;
    204. array_head const* GetHead()const { return &_array_head; }
    205. T_SHM_SIZE capacity()const { return _array_head.capacity; }
    206. T_SHM_SIZE size()const { return _array_head.size; }
    207. T_SHM_SIZE Capacity()const { return _array_head.capacity; }
    208. T_SHM_SIZE Size()const { return _array_head.size; }
    209. struct HANDLE
    210. {
    211. T_SHM_SIZE handle;
    212. };
    213. bool Add(TREE_NODE const& data, HANDLE& h)
    214. {
    215. if (_array_head.size == _array_head.capacity)return false;
    216. else
    217. {
    218. h.handle = _array_head.size;
    219. TREE_NODE::at(h.handle) = data;
    220. ++_array_head.size;
    221. return true;
    222. }
    223. }
    224. };
    225. private:
    226. TREE_HEAD _tree_head;
    227. private:
    228. //insert时如果已经存在保存被覆盖的数据
    229. bool m_OldValueSeted;
    230. T_DATA m_OldValue;
    231. public:
    232. T_SETARRAY m_array;//内置数组对象,存储实际数据
    233. TREE_HEAD* tree_head = &_tree_head;//指向树的头
    234. CRBTree() :m_OldValueSeted(false)
    235. {
    236. m_array._array_head.capacity = ARRAY_CAPACITY;
    237. m_array._array_head.size = 0;
    238. }
    239. T_SHM_SIZE size()const { return tree_head->size; }
    240. T_SHM_SIZE capacity()const { return m_array.GetHead()->capacity; }
    241. const_iterator begin()const
    242. {
    243. const_iterator it;
    244. if (-1 == tree_head->hHead)it.handle = -1;
    245. else it.handle = TREE_NODE::at(tree_head->hHead)._begin();
    246. return it;
    247. }
    248. const_iterator end()const
    249. {
    250. const_iterator it;
    251. it.handle = -1;
    252. return it;
    253. }
    254. bool _check_handle(T_SHM_SIZE h)const
    255. {
    256. return h >= -1 && h < m_array.GetHead()->size;
    257. }
    258. bool _check_is_data_node(T_SHM_SIZE h)const
    259. {
    260. return h >= 0 && h < m_array.GetHead()->size;
    261. }
    262. //获取节点总数,包括自身
    263. T_SHM_SIZE _check_get_count(T_SHM_SIZE h)
    264. {
    265. //thelog << h << endi;
    266. T_SHM_SIZE n = 0;
    267. if (_check_is_data_node(h))
    268. {
    269. ++n;
    270. //thelog << h << " " << TREE_NODE::at(h).hLeft<<" "<< TREE_NODE::at(h).hRight << endi;
    271. n += _check_get_count(TREE_NODE::at(h).hLeft);
    272. n += _check_get_count(TREE_NODE::at(h).hRight);
    273. }
    274. else
    275. {
    276. //thelog << "NULL" << endi;
    277. }
    278. return n;
    279. }
    280. //树形显示,px为偏移量,左边元素数
    281. void _check_show_tree(Table& table, T_SHM_SIZE h, bool left = true, T_SHM_SIZE line = 0, T_SHM_SIZE px = 0)
    282. {
    283. //thelog << h << " " << line << " " << px << endi;
    284. if (!_check_is_data_node(h))
    285. {
    286. //thelog << "空" << endi;
    287. return;
    288. }
    289. T_SHM_SIZE leftCount = _check_get_count(TREE_NODE::at(h).hLeft);
    290. //thelog << "leftCount " << leftCount << endi;
    291. T_SHM_SIZE pos = px + leftCount;
    292. table.SetData(line * 2, pos, TREE_NODE::at(h).toString2(left, false));//设置自身数据
    293. table.SetData(line * 2 + 1, pos, TREE_NODE::at(h).toString2(left, true));//设置自身数据
    294. //thelog << "TREE_NODE::at(h).hLeft " << TREE_NODE::at(h).hLeft << endi;
    295. _check_show_tree(table, TREE_NODE::at(h).hLeft, true, line + 1, px);//处理左子项
    296. //thelog << "TREE_NODE::at(h).hRight " << TREE_NODE::at(h).hRight << endi;
    297. _check_show_tree(table, TREE_NODE::at(h).hRight, false, line + 1, pos + 1);//处理右子项
    298. }
    299. void debug()
    300. {
    301. if (G_IS_DEBUG)
    302. {
    303. Table table;
    304. _check_show_tree(table, tree_head->hHead);
    305. thelog << endl << table.MakeTextTable() << endi;
    306. }
    307. }
    308. //检查红黑树特征
    309. bool _check_rbtree()
    310. {
    311. if (-1 == tree_head->hHead)return true;
    312. if (TREE_NODE::at(tree_head->hHead).bColorRed)
    313. {
    314. thelog << "根节点不是黑色" << ende;
    315. return false;
    316. }
    317. T_SHM_SIZE count_black = -1;
    318. if (_check_rbtree_count(tree_head->hHead, count_black, 0, 0, false))
    319. {
    320. debug_log << "深度 " << count_black << endi;
    321. return true;
    322. }
    323. else
    324. {
    325. return false;
    326. }
    327. }
    328. bool _check_rbtree_count(T_SHM_SIZE h, T_SHM_SIZE& count_black, T_SHM_SIZE black, T_SHM_SIZE red, bool PisRed)
    329. {
    330. if (-1 == h)
    331. {
    332. if (-1 == count_black)
    333. {
    334. count_black = black;
    335. return true;
    336. }
    337. else
    338. {
    339. if (black != count_black || red > black)
    340. {
    341. thelog << "深度不正确 " << count_black << " " << black << " " << red << ende;
    342. return false;
    343. }
    344. return true;
    345. }
    346. }
    347. else
    348. {
    349. if (TREE_NODE::at(h).bColorRed)
    350. {
    351. if (PisRed)
    352. {
    353. thelog << "连续红节点 " << h << ende;
    354. return false;
    355. }
    356. return _check_rbtree_count(TREE_NODE::at(h).hLeft, count_black, black, red + 1,true)
    357. && _check_rbtree_count(TREE_NODE::at(h).hRight, count_black, black, red + 1,true);
    358. }
    359. else
    360. return _check_rbtree_count(TREE_NODE::at(h).hLeft, count_black, black + 1, red,false)
    361. && _check_rbtree_count(TREE_NODE::at(h).hRight, count_black, black + 1, red,false);
    362. }
    363. }
    364. //检查数据结构是否正确
    365. bool _check()const
    366. {
    367. debug_log << "检查树结构,如果检查过程中发生数据修改则检查可能会出错" << endi;
    368. {
    369. size_t count_data_array = 0;//数组中的有效数据个数
    370. T_SHM_SIZE h;
    371. for (h = 0; h < static_cast(m_array.size()); ++h)
    372. {
    373. if (!TREE_NODE::at(h).deleted)++count_data_array;
    374. }
    375. debug_log << "数组容量 " << m_array.capacity() << " 个数 " << m_array.size() << " 有效数据 " << count_data_array << endi;
    376. debug_log << "树结构容量 " << capacity() << " 个数 " << size() << endi;
    377. if (count_data_array != size())
    378. {
    379. thelog << "树结构大小与数组统计不符 " << size() << " " << count_data_array << ende;
    380. return false;
    381. }
    382. }
    383. T_SHM_SIZE max_handle = m_array.GetHead()->size - 1;//整个已分配空间的最大句柄
    384. size_t count_free = 0;//未用节点数(删除的)
    385. //获取自由节点数
    386. {
    387. if (!_check_handle(tree_head->free_head))
    388. {
    389. thelog << "free_head error " << tree_head->free_head << ende;
    390. return false;
    391. }
    392. T_SHM_SIZE h = tree_head->free_head;
    393. while (h >= 0)
    394. {
    395. if (!TREE_NODE::at(h).deleted)
    396. {
    397. thelog << "此节点未被标记为删除 " << h << ende;
    398. return false;
    399. }
    400. ++count_free;
    401. if (TREE_NODE::at(h).hParent<-1 || TREE_NODE::at(h).hParent>max_handle)
    402. {
    403. thelog << "TREE_NODE::at(h).hParent error " << TREE_NODE::at(h).hParent << ende;
    404. return false;
    405. }
    406. h = TREE_NODE::at(h).hParent;
    407. }
    408. }
    409. if (count_free != m_array.size() - size())
    410. {
    411. thelog << "删除链表总数不正确 " << count_free << " " << m_array.size() - size() << ende;
    412. return false;
    413. }
    414. debug_log << "删除链表节点总数 " << count_free << endi;
    415. size_t count_used = 0;//已用节点数
    416. //获取已用节点数
    417. {
    418. T_COMP comp;
    419. iterator it = begin();
    420. iterator it_old = end();
    421. while (it != end())
    422. {
    423. if (!_check_handle(it.handle))
    424. {
    425. thelog << "无效的节点 " << it.handle << ende;
    426. return false;
    427. }
    428. if (TREE_NODE::at(it.handle).deleted)
    429. {
    430. thelog << "此节点被标记为删除 " << it.handle << ende;
    431. return false;
    432. }
    433. if (it_old == it)
    434. {
    435. thelog << "指针循环 [" << it_old.handle << "][" << it.handle << "]" << ende;
    436. return false;
    437. }
    438. if (it_old != end() && !comp(*it_old, *it))
    439. {
    440. string str1, str2;
    441. thelog << "节点数据比较错误 [" << it_old->toString(str1) << "][" << it->toString(str2) << "]" << ende;
    442. return false;
    443. }
    444. ++count_used;
    445. it_old = it;
    446. ++it;
    447. }
    448. }
    449. if (count_used != static_cast<size_t>(tree_head->size))
    450. {
    451. thelog << "begin->end != size " << count_used << " " << tree_head->size << ende;
    452. return false;
    453. }
    454. if (count_used != size())
    455. {
    456. thelog << "遍历获得节点数不正确 " << count_used << " " << size() << ende;
    457. return false;
    458. }
    459. debug_log << "检查完成,没有错误" << endi;
    460. return true;
    461. }
    462. private:
    463. //替换数据(只在插入时使用)
    464. void _update(T_SHM_SIZE position, T_DATA const& tmp)
    465. {
    466. TREE_NODE::at(position).data = tmp;
    467. }
    468. //修改头指针指向 src 的改为指向des(除了旋转只在删除里用到)
    469. void _changeRoot(T_SHM_SIZE src, T_SHM_SIZE des)
    470. {
    471. TREE_NODE::at(des).hParent = TREE_NODE::at(src).hParent;
    472. if (TREE_NODE::at(des).hParent != -1)
    473. {
    474. //旋转后是左节点
    475. if (TREE_NODE::at(TREE_NODE::at(des).hParent).hLeft == src)
    476. TREE_NODE::at(TREE_NODE::at(des).hParent).hLeft = des;
    477. //旋转后是右节点
    478. else
    479. TREE_NODE::at(TREE_NODE::at(des).hParent).hRight = des;
    480. }
    481. else
    482. {
    483. tree_head->hHead = des;
    484. }
    485. }
    486. //右旋转
    487. void _RRotate(T_SHM_SIZE p)
    488. {
    489. debug_log << "右旋" << p << endi;
    490. //assert(p>=0&&psize);
    491. //DEBUG_LOG<<"当前位置"<

      size <

    492. T_SHM_SIZE t_lchild = TREE_NODE::at(p).hLeft;
    493. TREE_NODE::at(p).hLeft = TREE_NODE::at(t_lchild).hRight;
    494. //右节点非空
    495. if (TREE_NODE::at(t_lchild).hRight != -1)
    496. TREE_NODE::at(TREE_NODE::at(t_lchild).hRight).hParent = p;
    497. //修改根节点父指针
    498. _changeRoot(p, t_lchild);
    499. TREE_NODE::at(p).hParent = t_lchild;
    500. TREE_NODE::at(t_lchild).hRight = p;
    501. }
    502. //左旋转
    503. void _LRotate(T_SHM_SIZE p)
    504. {
    505. debug_log << "左旋 " << p << endi;
    506. string tmp;
    507. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    508. T_SHM_SIZE t_rchild = TREE_NODE::at(p).hRight;
    509. debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
    510. TREE_NODE::at(p).hRight = TREE_NODE::at(t_rchild).hLeft;
    511. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    512. //右节点非空
    513. if (TREE_NODE::at(t_rchild).hLeft != -1)
    514. {
    515. TREE_NODE::at(TREE_NODE::at(t_rchild).hLeft).hParent = p;
    516. debug_log << "TREE_NODE::at(t_rchild).hLeft " << TREE_NODE::at(TREE_NODE::at(t_rchild).hLeft).toString(tmp) << endi;
    517. }
    518. //非根节点
    519. //DEBUG_LOG << "_LRotate t_rchild's parent" <
    520. //修改根节点父指针
    521. _changeRoot(p, t_rchild);
    522. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    523. debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
    524. TREE_NODE::at(p).hParent = t_rchild;
    525. TREE_NODE::at(t_rchild).hLeft = p;
    526. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    527. debug_log << "t_rchild " << TREE_NODE::at(t_rchild).toString(tmp) << endi;
    528. }
    529. //交换颜色
    530. void _exchage_color(T_SHM_SIZE a, T_SHM_SIZE b)
    531. {
    532. bool tmp = TREE_NODE::at(a).bColorRed;
    533. TREE_NODE::at(a).bColorRed = TREE_NODE::at(b).bColorRed;
    534. TREE_NODE::at(b).bColorRed = tmp;
    535. }
    536. //是否是红色,-1当作黑色
    537. bool _isRed(T_SHM_SIZE h)
    538. {
    539. return h != -1 && TREE_NODE::at(h).bColorRed;
    540. }
    541. //插入的入口
    542. pairbool> _insert(T_DATA const& tmp, T_COMP& comp)
    543. {
    544. pairbool> tmppair;
    545. T_SHM_SIZE insert_position = -1;
    546. bool isLeft = true;//插入节点方向 默认左插入
    547. bool isInsert = false;
    548. if ((insert_position = __insert(tmp, tree_head->hHead, -1, isLeft, isInsert, comp)) >= 0)
    549. {
    550. tmppair.first.handle = insert_position;
    551. tmppair.second = isInsert;
    552. //DEBUG_LOG<<"插入节点"<
    553. }
    554. else
    555. {
    556. //插入失败或者空间已满
    557. thelog << "插入节点失败" << ende;
    558. tmppair.first.handle = -1;
    559. tmppair.second = false;
    560. }
    561. TREE_NODE::at(tree_head->hHead).bColorRed = false;//根节点始终是黑色,因为转置的时候不能改颜色,所以只能在最后改
    562. return tmppair;
    563. }
    564. //插入节点返回-1不成功,vp父节点的子节点(即试图在此处插入),_parent父节点,taller 判断插入数据后节点深度是否增加
    565. T_SHM_SIZE __insert(T_DATA const& tmp, T_SHM_SIZE vp, T_SHM_SIZE _parent, bool isLeft, bool& isInsert, T_COMP& comp)
    566. {
    567. T_SHM_SIZE insert_position = -1;
    568. if (vp == -1)
    569. {
    570. //此位置为空,在此处插入
    571. insert_position = tree_head->free_head;
    572. ___insert_new(tmp, insert_position, _parent, isLeft, isInsert);
    573. //DEBUG_LOG<<"insert_position="<
    574. }
    575. else
    576. {
    577. //此位置有数据,根据比较结果处理
    578. if (comp(TREE_NODE::at(vp).data, tmp))
    579. {
    580. //大,走右边
    581. if ((insert_position = __insert(tmp, TREE_NODE::at(vp).hRight, vp, false, isInsert, comp)) == -1)
    582. {
    583. return -1;
    584. }
    585. }
    586. else if (comp(tmp, TREE_NODE::at(vp).data))
    587. {
    588. //小,走左边
    589. if ((insert_position = __insert(tmp, TREE_NODE::at(vp).hLeft, vp, true, isInsert, comp)) == -1)
    590. {
    591. return -1;
    592. }
    593. }
    594. else
    595. {
    596. //相等,更新数据
    597. //thelog<<"插入数据已经存在"<
    598. m_OldValue = TREE_NODE::at(vp).data;//保存被覆盖的值
    599. m_OldValueSeted = true;//设置被覆盖的对象有效
    600. _update(vp, tmp);
    601. return vp;
    602. }
    603. }
    604. return insert_position;
    605. }
    606. //插入新节点,position为新节点的位置,来自空闲列表,parent为父节点的位置
    607. void ___insert_new(T_DATA const& data, T_SHM_SIZE& position, T_SHM_SIZE parent, bool isLeft, bool& isInsert)
    608. {
    609. if (position < 0)
    610. {
    611. //没有空闲位置,需要动态扩展长度
    612. if (m_array.Capacity() > m_array.Size())
    613. {
    614. TREE_NODE tmp;
    615. typename T_SETARRAY::HANDLE h;
    616. if (!m_array.Add(tmp, h))
    617. {
    618. thelog << "扩展数组出错" << ende;
    619. isInsert = false;
    620. return;
    621. }
    622. else
    623. {
    624. //tree_head = m_array.GetUserHead();算法测试不用
    625. position = h.handle;
    626. }
    627. }
    628. else
    629. {
    630. thelog << "空间已满,请申请更大空间!!!!!!!!!!!!!!!!!!" << ende;
    631. isInsert = false;
    632. return;
    633. }
    634. }
    635. else
    636. {
    637. //thelog<<"exist position="<
    638. }
    639. tree_head->free_head = TREE_NODE::at(position).hParent;//空闲队列用hParent指向下一个
    640. //char buf[256];
    641. //sprintf(buf,"%ld %p",position,&TREE_NODE::at(position));
    642. //thelog<
    643. new(&TREE_NODE::at(position)) TREE_NODE(parent, data);
    644. //DEBUG_LOG<
    645. TREE_NODE::at(position).deleted = 0;
    646. if (parent == -1)
    647. {
    648. //没有父节点,空树
    649. tree_head->hHead = position;
    650. TREE_NODE::at(position).bColorRed = false;//根节点为黑色
    651. }
    652. else
    653. {
    654. //修改父节点
    655. //DEBUG_LOG<
    656. if (isLeft)
    657. {
    658. TREE_NODE::at(parent).hLeft = position;
    659. //DEBUG_LOG<
    660. }
    661. else
    662. {
    663. TREE_NODE::at(parent).hRight = position;
    664. //DEBUG_LOG<
    665. }
    666. //平衡处理
    667. _RB_insert_Balance(position);
    668. }
    669. isInsert = true;
    670. //DEBUG_LOG<<"新增节点"<
    671. ++tree_head->size;
    672. if (tree_head->size % 200000 == 0)
    673. {
    674. thelog << "树结构新增数据" << tree_head->size << endi;
    675. }
    676. }
    677. void _RB_insert_Balance(T_SHM_SIZE x)
    678. {
    679. T_SHM_SIZE p = TREE_NODE::at(x).hParent;
    680. if (!_isRed(p))return;
    681. //连续红,需要调整
    682. bool isLeft = (x == TREE_NODE::at(p).hLeft);
    683. T_SHM_SIZE g = TREE_NODE::at(p).hParent;
    684. bool isL = (p == TREE_NODE::at(g).hLeft);
    685. T_SHM_SIZE u = (isL ? TREE_NODE::at(g).hRight : TREE_NODE::at(g).hLeft);
    686. if (_isRed(u))
    687. {
    688. //u为红只需要染色,然后递归
    689. TREE_NODE::at(p).bColorRed = false;
    690. TREE_NODE::at(u).bColorRed = false;
    691. TREE_NODE::at(g).bColorRed = true;
    692. _RB_insert_Balance(g);
    693. }
    694. else
    695. {
    696. if (isL)
    697. {
    698. if (isLeft)
    699. {//LL
    700. _RRotate(g);
    701. _exchage_color(p, g);
    702. }
    703. else
    704. {//LR
    705. _LRotate(p);
    706. _RRotate(g);
    707. _exchage_color(x, g);
    708. }
    709. }
    710. else
    711. {
    712. if (isLeft)
    713. {//RL
    714. _RRotate(p);
    715. _LRotate(g);
    716. _exchage_color(x, g);
    717. }
    718. else
    719. {//RR
    720. _LRotate(g);
    721. _exchage_color(p, g);
    722. }
    723. }
    724. }
    725. }
    726. //删除指定节点,将节点接入到空闲链表
    727. void __erase_node(T_SHM_SIZE position)
    728. {
    729. debug_log << "删除节点 " << position << endi;
    730. TREE_NODE::at(position).hParent = tree_head->free_head;
    731. tree_head->free_head = position;
    732. TREE_NODE::at(position).hLeft = -1;
    733. TREE_NODE::at(position).hRight = -1;
    734. TREE_NODE::at(position).deleted = 1;
    735. --tree_head->size;
    736. }
    737. //删除中间节点,将中间节点替换为左子树最大值(数据不动,改变树结构)
    738. bool __erase_change_middle(T_SHM_SIZE const position, bool& vLeft, bool& vRed, T_SHM_SIZE& u, bool& uRed, T_SHM_SIZE& p)
    739. {
    740. string tmp;
    741. T_SHM_SIZE new_position = TREE_NODE::at(position).hLeft;
    742. if (-1 != new_position)
    743. {
    744. while (-1 != TREE_NODE::at(new_position).hRight)
    745. {
    746. new_position = TREE_NODE::at(new_position).hRight;
    747. }
    748. }
    749. debug_log << "position " << position << " new_position " << new_position << endi;
    750. debug_log << "position " << position << TREE_NODE::at(position).toString(tmp) << endi;
    751. debug_log << "new_position " << new_position << TREE_NODE::at(new_position).toString(tmp) << endi;
    752. vLeft = false;
    753. vRed = TREE_NODE::at(new_position).bColorRed;
    754. p = TREE_NODE::at(new_position).hParent;
    755. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    756. if (p != position)
    757. {
    758. debug_log << "非直接对调 p " << TREE_NODE::at(p).toString(tmp) << ende;
    759. TREE_NODE t;
    760. t._CopyWithoutData(TREE_NODE::at(new_position));
    761. TREE_NODE::at(new_position)._CopyWithoutData(TREE_NODE::at(position));
    762. TREE_NODE::at(position)._CopyWithoutData(t);
    763. debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
    764. debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
    765. //注意,这里无法用isLeft来判断,因为父节点的hLeft和hRight是旧数据
    766. if (TREE_NODE::at(new_position).hParent != -1)
    767. {
    768. if (TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft == position)TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft = new_position;
    769. else TREE_NODE::at(TREE_NODE::at(new_position).hParent).hRight = new_position;
    770. }
    771. if (TREE_NODE::at(position).hParent != -1)
    772. {
    773. if (TREE_NODE::at(TREE_NODE::at(position).hParent).hLeft==new_position)TREE_NODE::at(TREE_NODE::at(position).hParent).hLeft = position;
    774. else TREE_NODE::at(TREE_NODE::at(position).hParent).hRight = position;
    775. }
    776. if (TREE_NODE::at(new_position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(new_position).hLeft).hParent = new_position;
    777. if (TREE_NODE::at(position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(position).hLeft).hParent = position;
    778. if (TREE_NODE::at(new_position).hRight != -1)TREE_NODE::at(TREE_NODE::at(new_position).hRight).hParent = new_position;
    779. if (TREE_NODE::at(position).hRight != -1)TREE_NODE::at(TREE_NODE::at(position).hRight).hParent = position;
    780. }
    781. else
    782. {
    783. debug_log << "直接对调 p " << TREE_NODE::at(p).toString(tmp) << endi;
    784. TREE_NODE t;
    785. t._CopyWithoutData(TREE_NODE::at(new_position));
    786. TREE_NODE::at(new_position)._CopyWithoutData(TREE_NODE::at(position));
    787. TREE_NODE::at(position)._CopyWithoutData(t);
    788. debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
    789. debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
    790. //注意,这里无法用isLeft来判断,因为父节点的hLeft和hRight是旧数据
    791. if (TREE_NODE::at(new_position).hParent != -1)
    792. {
    793. if (TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft == position)TREE_NODE::at(TREE_NODE::at(new_position).hParent).hLeft = new_position;
    794. else TREE_NODE::at(TREE_NODE::at(new_position).hParent).hRight = new_position;
    795. }
    796. TREE_NODE::at(position).hParent = new_position;
    797. TREE_NODE::at(new_position).hLeft=position;
    798. if (TREE_NODE::at(position).hLeft != -1)TREE_NODE::at(TREE_NODE::at(position).hLeft).hParent = position;
    799. if (TREE_NODE::at(new_position).hRight != -1)TREE_NODE::at(TREE_NODE::at(new_position).hRight).hParent = new_position;
    800. if (TREE_NODE::at(position).hRight != -1)TREE_NODE::at(TREE_NODE::at(position).hRight).hParent = position;
    801. }
    802. //如果是根节点
    803. if (-1 == TREE_NODE::at(new_position).hParent)
    804. {
    805. TREE_NODE::at(new_position).bColorRed = false;
    806. tree_head->hHead = new_position;
    807. }
    808. debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
    809. debug_log << "new_position " << TREE_NODE::at(new_position).toString(tmp) << endi;
    810. debug();
    811. return true;
    812. }
    813. //删除时做平衡,u可能是空节点
    814. bool _RB_erase_Balance(T_SHM_SIZE p, T_SHM_SIZE u)
    815. {
    816. if (-1 == p)
    817. {
    818. debug_log << "已经到顶,结束" << endi;
    819. return true;
    820. }
    821. string tmp;
    822. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    823. if (u != -1)debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
    824. else debug_log << "u -1" << endi;
    825. bool isL = (u == TREE_NODE::at(p).hRight);//兄弟节点是否是左节点
    826. T_SHM_SIZE s = (isL ? TREE_NODE::at(p).hLeft : TREE_NODE::at(p).hRight);
    827. T_SHM_SIZE r = -1;//s的红色子节点
    828. bool is_rL;//s的红色子节点是否是左节点
    829. debug_log << "平衡:p " << p << " u " << u << " s " << s << " TREE_NODE::at(s).hRight " << TREE_NODE::at(s).hRight << endi;
    830. if (TREE_NODE::at(s).hRight != -1 && TREE_NODE::at(TREE_NODE::at(s).hRight).bColorRed)
    831. {
    832. r = TREE_NODE::at(s).hRight;
    833. is_rL = false;
    834. }
    835. else if (TREE_NODE::at(s).hLeft != -1 && TREE_NODE::at(TREE_NODE::at(s).hLeft).bColorRed)
    836. {
    837. r = TREE_NODE::at(s).hLeft;
    838. is_rL = true;
    839. }
    840. else
    841. {
    842. r = -1;
    843. is_rL = false;//无意义
    844. }
    845. debug_log << "p " << p << " u " << u << " s " << s << " r(-1表示双黑) " << r << endi;
    846. debug();
    847. if (-1 == r)
    848. {
    849. debug_log << "s子节点均为黑" << endi;
    850. if (TREE_NODE::at(p).bColorRed)
    851. {
    852. debug_log << "p为红,s必为黑 s改为红p改为黑 结束" << endi;//s子节点均为黑,p改为黑,所以s改为红是安全的,不会造成双红
    853. TREE_NODE::at(s).bColorRed = true;
    854. TREE_NODE::at(p).bColorRed = false;
    855. debug();
    856. }
    857. else
    858. {
    859. debug_log << "p为黑" << endi;
    860. if (!TREE_NODE::at(s).bColorRed)
    861. {
    862. debug_log << "s为黑 s改为红平衡下层并向上递归" << endi;//p的左右分支均少1,所以p成为新的双黑节点
    863. //置s为红,p为新的u,递归
    864. TREE_NODE::at(s).bColorRed = true;
    865. debug();
    866. return _RB_erase_Balance(TREE_NODE::at(p).hParent, p);
    867. }
    868. else
    869. {
    870. debug_log << "s为红 " << TREE_NODE::at(s).toString(tmp) << endi;
    871. debug_log << TREE_NODE::at(TREE_NODE::at(s).hParent).toString(tmp) << endi;
    872. if (TREE_NODE::at(s).isLeft())
    873. {
    874. debug_log << "s为左 " << s << endi;
    875. //右旋p
    876. _RRotate(p);
    877. }
    878. else
    879. {
    880. debug_log << "s为右" << endi;
    881. _LRotate(p);
    882. }
    883. //p和s变色
    884. TREE_NODE::at(s).bColorRed = false;
    885. TREE_NODE::at(p).bColorRed = true;
    886. debug();
    887. //此时深度情况不变,但p变成了红,重新对p和u做平衡处理
    888. return _RB_erase_Balance(p, u);
    889. }
    890. }
    891. }
    892. else
    893. {
    894. if (isL && is_rL)
    895. {
    896. debug_log << "LL" << ende;
    897. TREE_NODE::at(r).bColorRed = TREE_NODE::at(s).bColorRed;
    898. TREE_NODE::at(s).bColorRed = TREE_NODE::at(p).bColorRed;
    899. _RRotate(p);
    900. TREE_NODE::at(p).bColorRed = false;
    901. }
    902. else if (isL && !is_rL)
    903. {
    904. debug_log << "LR" << endi;
    905. debug();
    906. TREE_NODE::at(r).bColorRed = TREE_NODE::at(p).bColorRed;
    907. debug();
    908. _LRotate(s);
    909. debug();
    910. _RRotate(p);
    911. debug();
    912. TREE_NODE::at(p).bColorRed = false;
    913. debug();
    914. }
    915. else if (!isL && is_rL)
    916. {
    917. debug_log << "RL------------------------" << endi;
    918. debug();
    919. TREE_NODE::at(r).bColorRed = TREE_NODE::at(p).bColorRed;
    920. debug();
    921. _RRotate(s);
    922. debug();
    923. string tmp;
    924. debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    925. debug_log << "s " << TREE_NODE::at(p).toString(tmp) << endi;
    926. _LRotate(p);
    927. debug();
    928. TREE_NODE::at(p).bColorRed = false;
    929. debug();
    930. }
    931. else if (!isL && !is_rL)
    932. {
    933. debug_log << "RR" << endi;
    934. TREE_NODE::at(r).bColorRed = TREE_NODE::at(s).bColorRed;
    935. TREE_NODE::at(s).bColorRed = TREE_NODE::at(p).bColorRed;
    936. _LRotate(p);
    937. TREE_NODE::at(p).bColorRed = false;
    938. }
    939. else
    940. {
    941. thelog << "非预期的状态" << ende;
    942. return false;
    943. }
    944. }
    945. return true;
    946. }
    947. //删除
    948. bool _erase(T_SHM_SIZE position)
    949. {
    950. string report;
    951. //DEBUG_LOG<<"开始删除...."<
    952. bool vLeft;//删除的节点是左子节点
    953. bool vRed;//删除的节点是红色
    954. T_SHM_SIZE p = TREE_NODE::at(position).hParent;//父节点
    955. T_SHM_SIZE u;//替换节点
    956. bool uRed;//替换节点是红色(-1为黑色)
    957. if (TREE_NODE::at(position).hLeft != -1 && TREE_NODE::at(position).hRight != -1)
    958. {
    959. debug_log << "左右都存在,替换为左子树最大值" << endi;
    960. if (!__erase_change_middle(position, vLeft, vRed, u, uRed, p))return false;
    961. debug();
    962. return _erase(position);
    963. }
    964. else if (-1 == TREE_NODE::at(position).hLeft && -1 == TREE_NODE::at(position).hRight)
    965. {
    966. vLeft = TREE_NODE::at(position).isLeft();
    967. vRed = TREE_NODE::at(position).bColorRed;
    968. u = -1;
    969. uRed = false;
    970. if (-1 == p)
    971. {
    972. debug_log << "最后一个节点" << endi;
    973. tree_head->hHead = -1;
    974. vRed = true;//阻止后面继续处理,删除红色无需额外处理
    975. }
    976. else
    977. {
    978. debug_log << "叶子节点" << endi;
    979. if (TREE_NODE::at(position).isLeft())TREE_NODE::at(p).hLeft = -1;
    980. else TREE_NODE::at(p).hRight = -1;
    981. }
    982. }
    983. else
    984. {
    985. vLeft = TREE_NODE::at(position).isLeft();
    986. vRed = TREE_NODE::at(position).bColorRed;
    987. if (-1 != TREE_NODE::at(position).hLeft)
    988. {
    989. debug_log << "左子树存在" << endi;
    990. u = TREE_NODE::at(position).hLeft;
    991. }
    992. else
    993. {
    994. debug_log << "右子树存在" << endi;
    995. u = TREE_NODE::at(position).hRight;
    996. }
    997. if (-1 == p)
    998. {
    999. debug_log << "根节点" << endi;
    1000. tree_head->hHead = u;
    1001. }
    1002. else
    1003. {
    1004. if (vLeft)TREE_NODE::at(p).hLeft = u;
    1005. else TREE_NODE::at(p).hRight = u;
    1006. }
    1007. TREE_NODE::at(u).hParent = p;
    1008. uRed = TREE_NODE::at(u).bColorRed;
    1009. p = TREE_NODE::at(u).hParent;
    1010. }
    1011. bool ret = true;
    1012. if (vRed)
    1013. {
    1014. debug_log << "删除红色节点,不用调整" << endi;
    1015. //string tmp;
    1016. //debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
    1017. //debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    1018. //debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
    1019. //TREE_NODE::at(u).hParent = p;
    1020. //if (vLeft)TREE_NODE::at(p).hLeft = u;
    1021. //else TREE_NODE::at(p).hRight = u;
    1022. //debug_log << "position " << TREE_NODE::at(position).toString(tmp) << endi;
    1023. //debug_log << "p " << TREE_NODE::at(p).toString(tmp) << endi;
    1024. //debug_log << "u " << TREE_NODE::at(u).toString(tmp) << endi;
    1025. }
    1026. else if (!vRed && uRed)
    1027. {
    1028. debug_log << "删除黑色节点,替换节点红色改为黑色" << endi;
    1029. TREE_NODE::at(u).bColorRed = false;
    1030. }
    1031. else
    1032. {
    1033. debug_log << "删除双黑节点================================================" << endi;
    1034. ret = _RB_erase_Balance(p, u);
    1035. }
    1036. debug();
    1037. if (ret)__erase_node(position);
    1038. if (-1 != tree_head->hHead)TREE_NODE::at(tree_head->hHead).bColorRed = false;
    1039. return ret;
    1040. }
    1041. string show(T_SHM_SIZE position)
    1042. {
    1043. char buf[2048];
    1044. string tmp;
    1045. TREE_NODE::at(position).toString(tmp);
    1046. sprintf_s(buf, 2048, "%lld : %s", position, tmp.c_str());
    1047. return buf;
    1048. }
    1049. public:
    1050. //如果second为false则已经存在,发生了覆盖,用GetOldValue获得被覆盖的值
    1051. pairbool> insert(T_DATA const& data)
    1052. {
    1053. T_COMP comp;
    1054. return insert(data, comp);
    1055. }
    1056. pairbool> insert(T_DATA const& data, T_COMP& comp)
    1057. {
    1058. m_OldValueSeted = false;//清除被覆盖对象的有效标志
    1059. pairbool> ret;
    1060. ret.first = end();
    1061. ret.second = false;
    1062. if (tree_head->free_head < 0 && m_array.Capacity() <= m_array.Size())
    1063. {
    1064. thelog << "超出容量限制" << ende;
    1065. return ret;
    1066. }
    1067. try
    1068. {
    1069. ret = _insert(data, comp);
    1070. }
    1071. catch (exception& e)
    1072. {
    1073. thelog << e.what() << ende;
    1074. }
    1075. //thelog<<"insert ret "<
    1076. return ret;
    1077. }
    1078. //返回被覆盖的值,如果最近的操作没有发生覆盖则false
    1079. bool GetOldValue(T_DATA& ret)const
    1080. {
    1081. if (m_OldValueSeted)
    1082. {
    1083. ret = m_OldValue;
    1084. return true;
    1085. }
    1086. else
    1087. {
    1088. return false;
    1089. }
    1090. }
    1091. template<typename T_FIND >
    1092. const_iterator find(T_FIND const& tmp)const
    1093. {
    1094. T_COMP comp;
    1095. const_iterator it = lower_bound(tmp);
    1096. if (it != end())
    1097. {
    1098. if (comp(*it, tmp) || comp(tmp, *it))return end();
    1099. }
    1100. return it;
    1101. }
    1102. const_iterator find(T_DATA const& tmp, T_COMP& comp)const
    1103. {
    1104. const_iterator it = lower_bound(tmp, comp);
    1105. if (it != end())
    1106. {
    1107. if (comp(*it, tmp) || comp(tmp, *it))return end();
    1108. }
    1109. return it;
    1110. }
    1111. bool erase(const_iterator it)
    1112. {
    1113. T_COMP comp;
    1114. return erase(it, comp);
    1115. }
    1116. //删除并指向下一个
    1117. iterator& DeleteAndMoveNext(iterator& it)
    1118. {
    1119. if (end() == it)return it;
    1120. iterator& ret = it;
    1121. iterator tmp = ret;
    1122. ++ret;
    1123. erase(tmp);
    1124. return ret;
    1125. }
    1126. bool erase(const_iterator it, T_COMP& comp)
    1127. {
    1128. if (it.handle < 0)return true;
    1129. //DEBUG_LOG<<"要删除节点"<
    1130. bool ret = _erase(it.handle);
    1131. return ret;
    1132. }
    1133. bool erase(T_DATA const& data)
    1134. {
    1135. T_COMP comp;
    1136. return erase(data, comp);
    1137. }
    1138. bool erase(T_DATA const& data, T_COMP& comp)
    1139. {
    1140. const_iterator it = find(data, comp);
    1141. if (it.handle < 0)return true;
    1142. return erase(it, comp);
    1143. }
    1144. //用全比较函数,实际是find的功能
    1145. template<typename T_FIND >
    1146. const_iterator lower_bound(T_FIND const& tmp)const
    1147. {
    1148. T_COMP comp;
    1149. const_iterator it;
    1150. T_SHM_SIZE hNode = tree_head->hHead;
    1151. it.handle = -1;
    1152. while (-1 != hNode)
    1153. {
    1154. if (comp(tmp, TREE_NODE::at(hNode).data))
    1155. {
    1156. it.handle = hNode;
    1157. hNode = TREE_NODE::at(hNode).hLeft;
    1158. }
    1159. else if (comp(TREE_NODE::at(hNode).data, tmp))
    1160. {
    1161. hNode = TREE_NODE::at(hNode).hRight;
    1162. }
    1163. else
    1164. {
    1165. it.handle = hNode;
    1166. break;
    1167. }
    1168. }
    1169. return it;
    1170. }
    1171. //用部分比较函数(但必须是符合顺序的,否则结果不可预期)
    1172. template<typename T_FIND, typename T_LESS_BOUND >
    1173. const_iterator lower_bound(T_FIND const& tmp, T_LESS_BOUND comp)const
    1174. {
    1175. const_iterator it;
    1176. T_SHM_SIZE hNode = tree_head->hHead;
    1177. it.handle = -1;
    1178. while (-1 != hNode)
    1179. {
    1180. if (comp(tmp, TREE_NODE::at(hNode).data))
    1181. {
    1182. it.handle = hNode;
    1183. hNode = TREE_NODE::at(hNode).hLeft;
    1184. }
    1185. else if (comp(TREE_NODE::at(hNode).data, tmp))
    1186. {
    1187. hNode = TREE_NODE::at(hNode).hRight;
    1188. }
    1189. else
    1190. {
    1191. it.handle = hNode;
    1192. hNode = TREE_NODE::at(hNode).hLeft;
    1193. }
    1194. }
    1195. return it;
    1196. }
    1197. //用部分比较函数(但必须是符合顺序的,否则结果不可预期)
    1198. template<typename T_FIND, typename T_LESS_BOUND >
    1199. const_iterator upper_bound(T_FIND const& tmp, T_LESS_BOUND comp)const
    1200. {
    1201. const_iterator it;
    1202. T_SHM_SIZE hNode = tree_head->hHead;
    1203. it.handle = -1;
    1204. while (-1 != hNode)
    1205. {
    1206. if (comp(tmp, TREE_NODE::at(hNode).data))
    1207. {
    1208. it.handle = hNode;
    1209. hNode = TREE_NODE::at(hNode).hLeft;
    1210. }
    1211. else if (comp(TREE_NODE::at(hNode).data, tmp))
    1212. {
    1213. hNode = TREE_NODE::at(hNode).hRight;
    1214. }
    1215. else
    1216. {
    1217. hNode = TREE_NODE::at(hNode).hRight;
    1218. }
    1219. }
    1220. return it;
    1221. }
    1222. //检查一个节点是否已经删除,必须是有效参数
    1223. bool IsDeleted(T_SHM_SIZE handle)const
    1224. {
    1225. if (handle < 0 || handle >= m_array.capacity())return false;
    1226. return TREE_NODE::at(handle).deleted;
    1227. }
    1228. };

    四、测试代码main.cpp

    1. #include
    2. #include
    3. #include "rbtree.h"
    4. bool G_IS_DEBUG;
    5. TREE_NODE g_array[ARRAY_CAPACITY];
    6. TREE_NODE& TREE_NODE::at(T_SHM_SIZE n)
    7. {
    8. return g_array[n];
    9. }
    10. T_SHM_SIZE TREE_NODE::_me()const
    11. {
    12. return this - g_array;
    13. }
    14. //日志用格式
    15. string TimeToString_log(time_t const & t1)
    16. {
    17. if (0 == t1)return "";
    18. tm const * t2;
    19. char buf[256];
    20. t2 = localtime(&t1);
    21. sprintf(buf, "%02d-%02d %02d:%02d:%02d", t2->tm_mon + 1, t2->tm_mday, t2->tm_hour, t2->tm_min, t2->tm_sec);
    22. return buf;
    23. }
    24. bool test(int _seed, int count)
    25. {
    26. CRBTree rbtree;
    27. T_DATA a;
    28. srand(_seed);
    29. vector datas;
    30. for (T_SHM_SIZE i = 0; i < count; ++i)
    31. {
    32. datas.push_back(rand());
    33. }
    34. debug_log << rbtree.size() << " " << rbtree.capacity() << endi;
    35. for (T_SHM_SIZE v : datas)
    36. {
    37. a.n = v;
    38. debug_log << a.n << endi;
    39. rbtree.insert(a);
    40. }
    41. debug_log << rbtree.size() << " " << rbtree.capacity() << endi;
    42. rbtree._check();
    43. rbtree._check_rbtree();
    44. // CRBTree::const_iterator it = rbtree.begin();
    45. // for (; it != rbtree.end(); ++it)
    46. // {
    47. // string tmp1,tmp2;
    48. //thelog <<"h "<< it.handle << " 值:" << it->toString(tmp1) << " TREE_NODE:" << TREE_NODE::at(it.handle).toString(tmp2) << endi;
    49. // }
    50. Table table;
    51. rbtree._check_show_tree(table, rbtree.tree_head->hHead);
    52. debug_log << endl << table.MakeTextTable() << endi;
    53. bool ret = true;
    54. for (T_SHM_SIZE v : datas)
    55. {
    56. a.n = v;
    57. debug_log << a.n << endi;
    58. ret = rbtree.erase(a) && rbtree._check() && rbtree._check_rbtree();
    59. if (G_IS_DEBUG)
    60. {
    61. Table table;
    62. rbtree._check_show_tree(table, rbtree.tree_head->hHead);
    63. thelog << endl << table.MakeTextTable() << endi;
    64. }
    65. if (!ret)break;
    66. }
    67. //CRBTree::const_iterator it = rbtree.begin();
    68. //for (; it != rbtree.end(); ++it)
    69. //{
    70. // string tmp1, tmp2;
    71. // thelog << "h " << it.handle << " 值:" << it->toString(tmp1) << " TREE_NODE:" << TREE_NODE::at(it.handle).toString(tmp2) << endi;
    72. //}
    73. return ret;
    74. }
    75. int main()
    76. {
    77. G_IS_DEBUG = true;//大数据量测试时先设置为false,然后把后面循环的次数调大
    78. int count = 10;//每次测试的数据量,上限为 ARRAY_CAPACITY;
    79. for (int i = 0; i < 1; ++i)
    80. {
    81. if (!test(i, count))
    82. {
    83. G_IS_DEBUG = true;
    84. thelog << "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@" << endi;
    85. test(i, count);
    86. thelog << "失败 i= " << i << endi;
    87. return 1;
    88. }
    89. thelog << TimeToString_log(time(NULL)) << " " << i << endi;
    90. //break;
    91. }
    92. return 0;
    93. }

    五、运行效果

            以上三个代码就是全部代码,建立新工程,保存辅助代码和红黑树代码,用测试代码替换主代码,然后编译运行应该是没问题的。

            运行效果:

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

            最后结果:

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

    六、代码详解

            算法实战:亲自写红黑树之三 算法详解-CSDN博客

    (这里是结束)

  • 相关阅读:
    经验笔记 - 01_Vue+SpringBoot实现文件上传(单文件上传、单页面多处地方需要上传)
    文心一言 VS CHATGPT
    C题目11:数组a[m]排序
    maven的.m2文件夹
    2024懒人精灵七天从入门到精通实战课程(付源码)
    全链路压测的步骤及重要性
    Java知识梳理 第十二章 常用类
    怎么绕过CDN查找真实IP
    【手把手】ios苹果打包——遇见项目实战|超详细的教程分享
    LeetCode 287. 寻找重复数
  • 原文地址:https://blog.csdn.net/2301_77171572/article/details/134422111