• 二叉查找树(binary search tree)(难度7)


    C++数据结构与算法实现(目录)

    答案在此:二叉查找树(binary search tree)(答案)

    写在前面

    部分内容参《算法导论

    基本接口实现

    1 删除

    删除值为value的第一个节点

    删除叶子节点1

    删除叶子节点1

    (3)删除叶子节点1

    删除有两个孩子的节点z

    分成下面几个步骤进行:

    1 找到z的后继,y是z的后继。这时候可以确定y是不可能有左孩子的。

    2 删除y,让y的右孩子x取代自己的位置。删除只有一个孩子的节点上面已经讨论过。

    3 让y的值覆盖z的值。

    待实现代码

    1. #pragma once
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. using namespace std;
    14. //------下面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------
    15. #include
    16. #include
    17. #include
    18. #include
    19. #include
    20. using namespace std;
    21. struct Record { Record(void* ptr1, size_t count1, const char* location1, int line1, bool is) :ptr(ptr1), count(count1), line(line1), is_array(is) { int i = 0; while ((location[i] = location1[i]) && i < 100) { ++i; } }void* ptr; size_t count; char location[100] = { 0 }; int line; bool is_array = false; bool not_use_right_delete = false; }; bool operator==(const Record& lhs, const Record& rhs) { return lhs.ptr == rhs.ptr; }std::vector myAllocStatistic; void* newFunctionImpl(std::size_t sz, char const* file, int line, bool is) { void* ptr = std::malloc(sz); myAllocStatistic.push_back({ ptr,sz, file, line , is }); return ptr; }void* operator new(std::size_t sz, char const* file, int line) { return newFunctionImpl(sz, file, line, false); }void* operator new [](std::size_t sz, char const* file, int line)
    22. {
    23. return newFunctionImpl(sz, file, line, true);
    24. }void operator delete(void* ptr) noexcept { Record item{ ptr, 0, "", 0, false }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }void operator delete[](void* ptr) noexcept { Record item{ ptr, 0, "", 0, true }; auto itr = std::find(myAllocStatistic.begin(), myAllocStatistic.end(), item); if (itr != myAllocStatistic.end()) { auto ind = std::distance(myAllocStatistic.begin(), itr); myAllocStatistic[ind].ptr = nullptr; if (!itr->is_array) { myAllocStatistic[ind].not_use_right_delete = true; } else { myAllocStatistic[ind].count = 0; }std::free(ptr); } }
    25. #define new new(__FILE__, __LINE__)
    26. struct MyStruct { void ReportMemoryLeak() { std::cout << "Memory leak report: " << std::endl; bool leak = false; for (auto& i : myAllocStatistic) { if (i.count != 0) { leak = true; std::cout << "leak count " << i.count << " Byte" << ", file " << i.location << ", line " << i.line; if (i.not_use_right_delete) { cout << ", not use right delete. "; } cout << std::endl; } }if (!leak) { cout << "No memory leak." << endl; } }~MyStruct() { ReportMemoryLeak(); } }; static MyStruct my; void check_do(bool b, int line = __LINE__) { if (b) { cout << "line:" << line << " Pass" << endl; } else { cout << "line:" << line << " Ohh! not passed!!!!!!!!!!!!!!!!!!!!!!!!!!!" << " " << endl; exit(0); } }
    27. #define check(msg) check_do(msg, __LINE__);
    28. //------上面的代码是用来测试你的代码有没有问题的辅助代码,你无需关注------
    29. template<typename T>
    30. class binary_search_tree
    31. {
    32. private:
    33. struct tree_node//OK
    34. {
    35. tree_node() :data(T()){}
    36. tree_node(const T& t) :data(t){}
    37. bool exist_parent(void) const { return parent != nullptr; }
    38. T data;
    39. tree_node* parent = nullptr;
    40. tree_node* left = nullptr;
    41. tree_node* right = nullptr;
    42. };
    43. public:
    44. binary_search_tree(void) :m_root(nullptr) {}//默认构造函数:什么也不需要做,因为成员定义的时候就已经初始化了
    45. binary_search_tree(const T*, const int);//从数组构造一颗二叉树
    46. binary_search_tree(const binary_search_tree&);//拷贝构造函数
    47. binary_search_tree& operator = (const binary_search_tree&);
    48. ~binary_search_tree(void) { clear(); }//析构函数
    49. public:
    50. int size(void) const;//元素数量
    51. bool empty(void) const { return size() == 0; }//二叉树是否为空
    52. bool insert(const T& data);//插入一个元素
    53. T minmum(void) const;//最小值
    54. T maxmum(void) const;//最大值
    55. bool exists(const T& data) const;//判断元素是否存在
    56. void clear(void);//非递归清空二叉树
    57. void erase(const T& data);
    58. template<typename T>
    59. friend ostream& operator<<(ostream& out, const binary_search_tree& tree);//输出二叉树
    60. void print_pre_order_nonrecursive(void) const;//非递归:先序遍历输出二叉树
    61. void print_in_order_nonrecursive(void) const;//非递归:中序遍历输出二叉树
    62. void print_post_order_nonrecursive(void) const;//非递归:后续遍历输出二叉树
    63. void print_in_order_recursive(std::ostream& os) const;//递归中序遍历输出二叉树
    64. void print_element_order(void) const;//非递归按元素顺序输出二叉树
    65. std::string to_string_in_order(void) const;
    66. int max_length_between_node(void) const;//最大节点距离
    67. int hight(void) const;//树高度
    68. bool operator==(const binary_search_tree& other) const;//两个树相等:结构相同,对应元素相同
    69. bool operator!=(const binary_search_tree& other) const { return !equal(other); }//两个树不相等
    70. bool equal(const binary_search_tree& other) const;//两个树相等:结构相同,对应元素相同
    71. private:
    72. void print_binary_tree(ostream&, const tree_node* bt, int depth) const;//二叉树形式打印二叉树
    73. tree_node* find(const T& data);//查找
    74. tree_node* maxmum(tree_node*) const;//最大节点
    75. tree_node* minmum(tree_node*) const;//最小节点
    76. tree_node* successor(tree_node* t) const;//后继节点
    77. //节点的深度与高度:对于树中相同深度的每个结点来说,它们的高度不一定相同,这取决于每个结点下面的叶结点的深度
    78. int hight(const tree_node* _t) const;
    79. bool equal(const tree_node* lhs, const tree_node* rhs) const;//两个树相等:结构相同,对应元素相同
    80. bool is_node_leaf(const tree_node* node) const;
    81. bool is_left_child(const tree_node* parent, const tree_node* node);
    82. bool is_leaf_node_equal(const tree_node* lhs, const tree_node* rhs) const;
    83. void copy(const binary_search_tree& other);
    84. void copy_node_from(tree_node*& dest, tree_node* dest_parent, const tree_node* from);
    85. void print_in_order_recursive(std::ostream& os
    86. , const tree_node* node) const;//递归中序遍历输出二叉树
    87. void erase_node(tree_node*& pnode);//参数是引用类型,主要是为了:erase_node(m_root) 时,更新m_root;
    88. void erase_and_reconnect(tree_node*& pnode, tree_node* pnode_child);
    89. void update_parent(tree_node* pnode);//删除叶子结点后,让父节点指向空指针
    90. private:
    91. tree_node* left(tree_node* p)
    92. {
    93. assert(p != nullptr);
    94. return p->left;
    95. }
    96. private:
    97. tree_node* m_root = nullptr;//OK
    98. int m_size = 0;
    99. };
    100. template<typename T>
    101. std::string binary_search_tree::to_string_in_order(void) const
    102. {
    103. std::stringstream oss;
    104. this->print_in_order_recursive(oss);
    105. auto str = oss.str();
    106. return str;
    107. }
    108. template<typename T>
    109. binary_search_tree::binary_search_tree(const T* arr, const int length) : binary_search_tree()
    110. {
    111. //(4) your code
    112. //可以使用成员函数insert(const T& data) 来实现这个函数
    113. }
    114. template<typename T>
    115. inline binary_search_tree::binary_search_tree(const binary_search_tree & from) :m_root(nullptr)
    116. {
    117. //(5) your code
    118. //可以使用成员函数copy来实现
    119. }
    120. template<typename T>
    121. binary_search_tree& binary_search_tree::operator=(const binary_search_tree & from)
    122. {
    123. //(5) your code
    124. //可以使用成员函数copy来实现。
    125. //从这里可以看出copy函数应该先用clear成员函数清空自己原有的全部节点
    126. return *this;
    127. }
    128. template<typename T>
    129. void binary_search_tree::copy(const binary_search_tree& other)
    130. {
    131. if (this == &other)//如果拷贝自己,则什么也不做
    132. {
    133. return;//直接返回
    134. }
    135. clear();//先清空自己的内容
    136. m_size = other.m_size;//成员变量赋值
    137. if (other.m_root)//从根节点开始拷贝;递归的拷贝二叉树的每一个节点,照葫芦画瓢
    138. {
    139. copy_node_from(m_root/*需要被创建的节点*/, nullptr/*需要被创建的节点的父节点:用户指向孩子*/, other.m_root/*提供节点存储的数据*/);
    140. }
    141. }
    142. template<typename T>
    143. bool binary_search_tree::insert(const T& data)
    144. {
    145. if (m_root != nullptr)
    146. {
    147. tree_node *fast, *slow, *ptemp;
    148. fast = slow = ptemp = m_root;
    149. while (fast != 0)
    150. {
    151. slow = fast;
    152. if (data < slow->data)
    153. {
    154. fast = slow->left;
    155. }
    156. else if (data > slow->data)
    157. {
    158. fast = slow->right;
    159. }
    160. else
    161. //esle equal do nothing 元素不允许重复
    162. //,元素如果已经存在,什么也不做
    163. {
    164. fast = 0;
    165. return false;//直接退出,不再插入相同的元素的
    166. }
    167. }
    168. if (data < slow->data)
    169. {
    170. slow->left = new tree_node(data);
    171. slow->left->parent = slow;
    172. }
    173. else if (data > slow->data)
    174. {
    175. slow->right = new tree_node(data);
    176. slow->right->parent = slow;
    177. }
    178. else
    179. {
    180. return false;
    181. }
    182. //esle equal do nothing
    183. }
    184. else
    185. {
    186. m_root = new tree_node(data);
    187. }
    188. ++m_size;
    189. return true;
    190. }
    191. template<typename T>
    192. int binary_search_tree::hight(void) const
    193. {
    194. return hight(m_root);
    195. }
    196. template<typename T>
    197. int binary_search_tree::hight(const tree_node* _t) const
    198. {
    199. //树的高度,也是树的层树,最大层的层数就是树的高度
    200. //(7) your code 如果没有元素,返回0
    201. // 如果只有一个根节点,没有孩子节点高度为1
    202. // 如果有孩子节点,树的高度就 = 1 + 孩子节点的高度(左右子树高度较大的那一个)
    203. return -1;
    204. }
    205. template<typename T>
    206. bool binary_search_tree::operator==(const binary_search_tree & other) const
    207. {
    208. return this->equal(other);//两个二叉树相等,当且仅当两颗树长的一模一样
    209. }
    210. template<typename T>
    211. bool binary_search_tree::equal(const binary_search_tree & other) const
    212. {
    213. return equal(m_root, other.m_root);
    214. }
    215. template<typename T>
    216. bool binary_search_tree::equal(const tree_node* lhs, const tree_node* rhs) const
    217. {
    218. // 先判断两个树是否为空
    219. //再判断两个树是否都是叶子节点 可以使用 is_leaf_node_equal 成员函数
    220. //再判断两个树的两个左右子树是否同时相等 可以递归调用当前equal函数
    221. //(8) your code
    222. return false;
    223. }
    224. template<typename T>
    225. inline bool binary_search_tree::is_leaf_node_equal(const tree_node* lhs
    226. , const tree_node* rhs) const
    227. {
    228. if (is_node_leaf(lhs) && is_node_leaf(rhs))
    229. {
    230. return lhs->data == rhs->data;
    231. }
    232. return false;
    233. }
    234. template<typename T>
    235. inline bool binary_search_tree::is_node_leaf(const tree_node * node) const
    236. {
    237. return node != nullptr && node->left == nullptr && node->right == nullptr;
    238. }
    239. template<typename T>
    240. ///*需要被创建的节点*/, nullptr/*需要被创建的节点*/, other.m_root/*提供节点存储的数据*/
    241. void binary_search_tree::copy_node_from(tree_node *& dest, tree_node* dest_parent, const tree_node * from)
    242. {
    243. //(9) your code 深度拷贝from节点,并切递归拷贝,从而完成整棵树的拷贝
    244. //注意dest节点传递的是引用,这意味着你可以非常方便的对这个地址变量赋值,赋值就会修改传进来的外部变量
    245. //改函数使用递归调用自己的方式,完成整棵树的拷贝。注意对左子树和又子树可能需要分别调用一次递归函数才能完成。
    246. }
    247. template<typename T>
    248. int binary_search_tree::max_length_between_node(void) const
    249. {
    250. int max_length = 0;
    251. const tree_node* ptree = m_root;
    252. list listNode;
    253. listNode.push_back(m_root);
    254. while (!listNode.empty())
    255. {
    256. auto pnode = listNode.front();
    257. listNode.pop_front();
    258. if (pnode->left != nullptr)
    259. {
    260. listNode.push_back(pnode->left);
    261. }
    262. if (pnode->right != nullptr)
    263. {
    264. listNode.push_back(pnode->right);
    265. }
    266. int tempBetween = hight(pnode->left) + hight(pnode->right);
    267. max_length = std::max<int>(tempBetween, max_length);
    268. }
    269. return max_length;
    270. }
    271. template<typename T>
    272. void binary_search_tree::clear(void)
    273. {
    274. //使用一个辅助队列(或者栈),层次遍历删除所有节点。
    275. //遍历到一个节点A就把孩子BC放到队列,并把这个节点A从队列里取出释放
    276. //(10) your code
    277. }
    278. template<typename T>
    279. void binary_search_tree::print_binary_tree(ostream& out, const tree_node* bt, int depth) const
    280. {
    281. //用右左孩子的方式输出一颗树,先输出右孩子后输出左孩子
    282. if (bt)
    283. {
    284. print_binary_tree(out, bt->right, depth + 1);
    285. if (depth == 0)
    286. {
    287. out << bt->data << endl;
    288. }
    289. else if (depth == 1)
    290. {
    291. out << " --" << bt->data << endl;
    292. }
    293. else
    294. {
    295. int n = depth;
    296. while (--n)
    297. {
    298. cout << " ";
    299. }
    300. out << " --" << bt->data << endl;
    301. }
    302. print_binary_tree(out, bt->left, depth + 1);
    303. }
    304. }
    305. template<typename T>
    306. void binary_search_tree::print_in_order_nonrecursive(void) const
    307. {
    308. cout << "print_in_order_nonrecursive : ";
    309. stack tempstack;
    310. tree_node* t = m_root;
    311. if (t != NULL)
    312. {
    313. do
    314. {
    315. tempstack.push(t);
    316. t = t->left;
    317. } while (t != NULL);
    318. }
    319. while (!tempstack.empty())
    320. {
    321. tree_node* p = tempstack.top();
    322. cout << p->data << " ";
    323. tempstack.pop();
    324. if (p->right != NULL)
    325. {
    326. p = p->right;
    327. do
    328. {
    329. tempstack.push(p);
    330. p = p->left;
    331. } while (p != NULL);
    332. }
    333. }
    334. cout << endl;
    335. }
    336. template<typename T>
    337. inline void binary_search_tree::print_in_order_recursive(std::ostream & os) const
    338. {
    339. print_in_order_recursive(os, m_root);
    340. }
    341. template<typename T>
    342. void binary_search_tree::print_in_order_recursive(std::ostream & os, const tree_node * node) const
    343. {
    344. if (node == nullptr)
    345. {
    346. return;
    347. }
    348. print_in_order_recursive(os, node->left);
    349. os << node->data << " ";
    350. print_in_order_recursive(os, node->right);
    351. }
    352. template<typename T>
    353. ostream& operator<<(ostream& out, const binary_search_tree& tree)
    354. {
    355. tree.print_binary_tree(out, tree.m_root, 0);
    356. return out;
    357. }
    358. template<typename T>
    359. void binary_search_tree::print_post_order_nonrecursive(void) const
    360. {
    361. //后续序序遍历输出一颗树的全部结点值2,3,1
    362. //广度优先遍历
    363. cout << "print_post_order_nonrecursive : ";
    364. typedef pairbool> multinode;
    365. stack tempstack;
    366. if (m_root)
    367. {
    368. tempstack.push(make_pair(m_root, false));
    369. }
    370. while (!tempstack.empty())
    371. {
    372. multinode m = tempstack.top(); tempstack.pop();
    373. if (m.first->left == NULL && m.first->right == NULL)
    374. {//叶子节点直接输出
    375. cout << m.first->data << " ";
    376. }
    377. else if (m.second == true)
    378. {//所有孩子都遍历完了才会到这一步
    379. cout << m.first->data << " ";
    380. }
    381. else
    382. {//非终结点,并且孩子还没遍历完。
    383. m.second = true; tempstack.push(m);
    384. if (m.first->right != NULL)
    385. {
    386. tempstack.push(make_pair(m.first->right, false));
    387. }
    388. if (m.first->left != NULL)
    389. {
    390. tempstack.push(make_pair(m.first->left, false));
    391. }
    392. }
    393. }
    394. cout << endl;
    395. }
    396. template<typename T>
    397. void binary_search_tree::print_pre_order_nonrecursive(void) const
    398. {
    399. //先序遍历输出一颗树的全部结点值1,2,3,先根遍历
    400. cout << "print_pre_order_nonrecursive : ";
    401. stack node_stack;
    402. if (m_root)
    403. {
    404. node_stack.push(m_root);
    405. tree_node* t;
    406. while (!node_stack.empty())
    407. {
    408. t = node_stack.top();
    409. node_stack.pop();
    410. cout << t->data << " ";
    411. if (t->right != 0)
    412. {
    413. node_stack.push(t->right);
    414. }
    415. if (t->left != 0)
    416. {
    417. node_stack.push(t->left);
    418. }
    419. }
    420. cout << endl;
    421. }
    422. }
    423. template<typename T>
    424. bool binary_search_tree::exists(const T& data) const
    425. {
    426. bool result = false;
    427. if (m_root)
    428. {
    429. tree_node* pfind = m_root;
    430. while (pfind)
    431. {
    432. if (pfind->data == data)
    433. {
    434. result = true;
    435. break;
    436. }
    437. else if (data < pfind->data)
    438. {
    439. pfind = pfind->left;
    440. }
    441. else
    442. pfind = pfind->right;
    443. }
    444. }
    445. return result;
    446. }
    447. template<typename T>
    448. typename binary_search_tree::tree_node* binary_search_tree::find(const T& data)
    449. {
    450. //(11) your code 利用find,非递归实现:查找某个值是否存在于树中
    451. return nullptr;
    452. }
    453. template<typename T>
    454. int binary_search_tree::size(void) const
    455. {
    456. return m_size;
    457. }
    458. template<typename T>
    459. T binary_search_tree::minmum(void) const
    460. {
    461. //(12) your code 返回最小值 ,请使用成员函数 minmum(tree_node* p) const 来实现
    462. return T();
    463. }
    464. template<typename T>
    465. typename binary_search_tree::tree_node* binary_search_tree::minmum(tree_node* p) const
    466. {
    467. //(13) your code 返回最小值:非递归实现
    468. return nullptr;
    469. }
    470. template<typename T>
    471. T binary_search_tree::maxmum(void) const
    472. {
    473. //(14) your code 返回最大值 ,请使用成员函数 maxmum(tree_node* p) const 来实现
    474. return T();
    475. }
    476. template<typename T>
    477. typename binary_search_tree::tree_node* binary_search_tree::maxmum(tree_node* t) const
    478. {
    479. //(14) your code 返回最大值:非递归实现
    480. return nullptr;
    481. }
    482. template<typename T>
    483. typename binary_search_tree::tree_node* binary_search_tree::successor(tree_node* t) const
    484. {
    485. //(15) your code 找到一个节点的后继结点,这个函数是顺序迭代遍历二叉树的关键函数。
    486. //具体思路为,如果这个节点有右子树,那么右子树的minmum节点就是后继结点。
    487. //如果,这个节点没有右子树,比该节点大的值,一定是往右上方去的第一个节点。
    488. //参考《算法导论》
    489. return nullptr;
    490. }
    491. template<typename T>
    492. void binary_search_tree::print_element_order(void) const
    493. {
    494. cout << "print_element_order by order: ";
    495. if (!empty())
    496. {
    497. //(16) your code 使用后继节点成员函数作为顺序迭代的依据,实现顺序遍历一颗二次函数。
    498. //循环获取后继,只要有后继,就输出这个后继。
    499. cout << endl;
    500. }
    501. }
    502. template<typename T>
    503. void binary_search_tree::erase(const T& data)
    504. {
    505. tree_node* itr = find(data);
    506. assert(itr != nullptr);
    507. --m_size;
    508. if (itr == m_root)
    509. {
    510. /*删除根节点,可能需要释放根节点本身,这个时候m_root的指向需要更新。
    511. * 所以erase_node的参数是引用类型,希望可以在erase_node内部对m_root重新
    512. * 赋值来打到更新根节点指向的目的。
    513. */
    514. erase_node(m_root);
    515. return;
    516. }
    517. else
    518. {
    519. erase_node(itr);
    520. }
    521. }
    522. template<typename T>
    523. void binary_search_tree::erase_node(tree_node*& pnode)
    524. {
    525. //pnode如果没有parent,那么它就是root,这个时候,删除pnode
    526. // ,无需考虑pnode的parent需要更新的问题。
    527. //只需要处理其孩子替代自己的问题
    528. if (pnode->left == nullptr && pnode->right == nullptr)
    529. {
    530. //叶子结点被删除了的话,被删除节点的父亲应该指向空指针。
    531. update_parent(pnode);//内部会先判断pnode有没有parent
    532. delete pnode;
    533. //这里会更新传进来的引用参数,比如,如果传进来的是m_root的话。
    534. pnode = nullptr;//如果pnode是m_root的话,这句话就会变得必不可少(更新m_root)
    535. }
    536. //如果被删除的节点p只有左孩子:让p的左孩子p_left_child取代自己作为p的parent节点的做孩子
    537. else if (pnode->left != nullptr && pnode->right == nullptr)
    538. {
    539. //让pnode的父亲节点和pnode的孩子建立连接
    540. erase_and_reconnect(pnode, pnode->left);
    541. }
    542. //如果只有右孩子:让右孩子取代自己
    543. else if (pnode->left == nullptr && pnode->right != nullptr)
    544. {
    545. //让pnode的父亲节点和pnode的孩子建立连接
    546. erase_and_reconnect(pnode, pnode->right);
    547. }
    548. else
    549. {
    550. //https://zhuanlan.zhihu.com/p/640863892
    551. //分成下面几个步骤进行:
    552. //1 找到z的后继,y是z的后继。这时候可以确定y是不可能有左孩子的。
    553. //2 删除y,让y的右孩子x取代自己的位置。删除只有一个孩子的节点上面已经讨论过。
    554. //3 让y的值覆盖z的值。
    555. tree_node* psuccessor = successor(pnode);
    556. pnode->data = psuccessor->data;//3 让y的值覆盖z的值。
    557. //2 删除y, y只有一个孩子,只有一个孩子的节点删除此函数的开始部分已经实现了。只需要调用此函数即可。
    558. //(17) your code
    559. }
    560. }
    561. template<typename T>
    562. void binary_search_tree::update_parent(tree_node* pnode)
    563. {//删除叶子结点后,让父节点指向空指针
    564. if (pnode->parent)
    565. {
    566. auto parent = pnode->parent;
    567. is_left_child(parent, pnode) ? (parent->left = nullptr) : (parent->right = nullptr);
    568. }
    569. }
    570. template<typename T>
    571. void binary_search_tree::erase_and_reconnect(tree_node*& delete_pnode, tree_node* pnode_child)
    572. {
    573. //让左孩子取代自己,同时考虑parent不存在的情况下取代自己。
    574. if (delete_pnode->exist_parent())
    575. {
    576. //拿到父节点
    577. auto parent = delete_pnode->parent;
    578. auto is_left = is_left_child(parent, delete_pnode);
    579. //先备份地址,将来用于释放内存
    580. auto pbackup = delete_pnode;
    581. //指向新节点:自己的左孩子替代自己
    582. // reconnect1 ->
    583. delete_pnode = pnode_child;
    584. // <- reconnect2
    585. pnode_child->parent = parent;//指向新的父亲
    586. //删除自己原来的内存
    587. delete pbackup;
    588. //父节点和自己的左孩子建立连接
    589. is_left ? parent->left = delete_pnode : parent->right = delete_pnode;
    590. }
    591. else //删除根节点, 删除根节点可不是删除整个树哦
    592. {
    593. //先备份地址,将来用于释放内存
    594. auto pbackup = delete_pnode;
    595. //指向新节点:自己的左孩子替代自己
    596. delete_pnode = pnode_child;
    597. //删除自己原来的内存
    598. delete pbackup;
    599. }
    600. }
    601. template<typename T>
    602. bool binary_search_tree::is_left_child(const tree_node* parent, const tree_node* pnode)
    603. {
    604. assert(parent != nullptr);
    605. assert(pnode != nullptr);
    606. return (parent->left == pnode);
    607. }
    608. void test_tree(const binary_search_tree<int>& _tree)
    609. {
    610. cout << "test_tree:\n";
    611. cout << _tree;
    612. cout << "tree size : " << _tree.size() << endl;
    613. cout << "tree max length between node " << _tree.max_length_between_node() << endl;
    614. _tree.print_in_order_nonrecursive();
    615. _tree.print_element_order();
    616. _tree.print_post_order_nonrecursive();
    617. _tree.print_pre_order_nonrecursive();
    618. cout << "min element : " << _tree.minmum() << endl;
    619. cout << "max element : " << _tree.maxmum() << "\n" << endl;
    620. }
    621. void test1()
    622. {
    623. binary_search_tree<int> tree;
    624. check(tree.size() == 0);
    625. check(tree.empty());
    626. check(tree.hight() == 0);
    627. }
    628. void test2()
    629. {
    630. int arr[1] = { 1 };
    631. binary_search_tree<int> tree(arr, 1);
    632. check(tree.size() == 1);
    633. check(tree.to_string_in_order() == "1 ");
    634. check(!tree.empty());
    635. }
    636. void test3()
    637. {
    638. int arr[2] = { 1, 2 };
    639. binary_search_tree<int> tree(arr, 2);
    640. check(tree.size() == 2);
    641. check(tree.to_string_in_order() == "1 2 ");
    642. check(!tree.empty());
    643. }
    644. void test4()
    645. {
    646. int arr[2] = { 2, 1 };
    647. binary_search_tree<int> tree(arr, 2);
    648. check(tree.size() == 2);
    649. check(tree.to_string_in_order() == "1 2 ");
    650. check(!tree.empty());
    651. }
    652. void test5()
    653. {
    654. constexpr int length = 3;
    655. int arr[length] = { 1, 2, 3 };
    656. binary_search_tree<int> tree(arr, length);
    657. check(tree.size() == length);
    658. check(tree.to_string_in_order() == "1 2 3 ");
    659. check(!tree.empty());
    660. }
    661. void test6()
    662. {
    663. constexpr int length = 3;
    664. int arr[length] = { 2, 1, 3 };
    665. binary_search_tree<int> tree(arr, length);
    666. check(tree.size() == length);
    667. check(tree.to_string_in_order() == "1 2 3 ");
    668. check(!tree.empty());
    669. }
    670. void test7()
    671. {
    672. constexpr int length = 3;
    673. int arr[length] = { 3, 2, 1, };
    674. binary_search_tree<int> tree(arr, length);
    675. check(tree.size() == length);
    676. check(tree.to_string_in_order() == "1 2 3 ");
    677. check(!tree.empty());
    678. }
    679. void test8()
    680. {
    681. constexpr int length = 3;
    682. int arr[length] = { 3, 1, 2, };
    683. binary_search_tree<int> tree(arr, length);
    684. check(tree.size() == length);
    685. check(tree.to_string_in_order() == "1 2 3 ");
    686. check(!tree.empty());
    687. }
    688. void test9()
    689. {
    690. constexpr int length = 10;
    691. int arr[length] = { 1,3,5,7,9,2,4,6,8,10 };
    692. binary_search_tree<int> tree(arr, length);
    693. check(tree.size() == length);
    694. check(tree.to_string_in_order() ==
    695. "1 2 3 4 5 6 7 8 9 10 ");
    696. check(!tree.empty());
    697. }
    698. void test10()
    699. {
    700. constexpr int length = 10;
    701. int arr[length] = { 2,4,6,8,10,1,3,5,7,9 };
    702. binary_search_tree<int> tree(arr, length);
    703. check(tree.size() == length);
    704. check(tree.to_string_in_order() ==
    705. "1 2 3 4 5 6 7 8 9 10 ");
    706. check(!tree.empty());
    707. }
    708. void test11()
    709. {
    710. constexpr int length = 10;
    711. int arr[length] = { 10,9,8,7,6,5,4,3,2,1 };
    712. binary_search_tree<int> tree(arr, length);
    713. check(tree.size() == length);
    714. check(tree.to_string_in_order() ==
    715. "1 2 3 4 5 6 7 8 9 10 ");
    716. check(!tree.empty());
    717. check(tree.hight() == 10);
    718. }
    719. void test12()
    720. {
    721. constexpr int length = 10;
    722. int arr[length] = { 5,4,3,2,1,10,9,8,7,6 };
    723. binary_search_tree<int> tree(arr, length);
    724. check(tree.size() == length);
    725. check(tree.to_string_in_order() ==
    726. "1 2 3 4 5 6 7 8 9 10 ");
    727. check(!tree.empty());
    728. check(tree.hight() == 6);
    729. }
    730. void test13()
    731. {
    732. constexpr int length = 1;
    733. int arr[length] = { 1 };
    734. binary_search_tree<int> tree(arr, length);
    735. check(tree.minmum() == 1);
    736. check(tree.maxmum() == 1);
    737. check(tree.hight() == 1);
    738. }
    739. void test14()
    740. {
    741. constexpr int length = 2;
    742. int arr[length] = { 1, 2 };
    743. binary_search_tree<int> tree(arr, length);
    744. check(tree.minmum() == 1);
    745. check(tree.maxmum() == 2);
    746. check(tree.hight() == 2);
    747. }
    748. void test15()
    749. {
    750. constexpr int length = 10;
    751. int arr[length] = { 5,4,3,2,1,10,9,8,7,6 };
    752. binary_search_tree<int> tree(arr, length);
    753. check(tree.minmum() == 1);
    754. check(tree.maxmum() == 10);
    755. }
    756. void test16()
    757. {
    758. constexpr int length = 1;
    759. int arr[length] = { 1 };
    760. binary_search_tree<int> tree(arr, length);
    761. check(tree.exists(1));
    762. tree.erase(1);
    763. check(!tree.exists(1));
    764. check(tree.size() == 0);
    765. }
    766. void test17()
    767. {
    768. int arr[] = { 3,2,1 };
    769. binary_search_tree<int> tree(arr, sizeof(arr) / sizeof(int));
    770. check(tree.exists(1));
    771. cout << tree << endl;
    772. tree.erase(2);
    773. cout << tree << endl;
    774. check(!tree.exists(2));
    775. check(tree.size() == 2);
    776. check(!tree.empty());
    777. check(tree.to_string_in_order() == "1 3 ");
    778. }
    779. void test18()
    780. {
    781. constexpr int length = 2;
    782. int arr[length] = { 1, 2 };
    783. binary_search_tree<int> tree(arr, length);
    784. check(tree.exists(1));
    785. check(tree.exists(2));
    786. tree.erase(1);
    787. check(!tree.exists(1));
    788. check(tree.exists(2));
    789. tree.clear();
    790. check(tree.empty());
    791. check(tree.size() == 0);
    792. check(!tree.exists(2));
    793. }
    794. void test19()
    795. {
    796. constexpr int length = 10;
    797. int arr[length] = { 5,3,4,1,2,10,8,9,7,6 };
    798. binary_search_tree<int> tree(arr, length);
    799. cout << tree << endl << "-------------------" << endl;
    800. tree.erase(1);
    801. cout << tree << endl << "-------------------" << endl;
    802. check(tree.to_string_in_order() == "2 3 4 5 6 7 8 9 10 ");
    803. tree.erase(2);
    804. cout << tree << endl << "-------------------" << endl;
    805. check(tree.to_string_in_order() == "3 4 5 6 7 8 9 10 ");
    806. tree.erase(3);
    807. check(tree.to_string_in_order() == "4 5 6 7 8 9 10 ");
    808. cout << tree << endl << "-------------------" << endl;
    809. tree.erase(4);
    810. cout << tree << endl << "-------------------" << endl;
    811. check(tree.to_string_in_order() == "5 6 7 8 9 10 ");
    812. tree.erase(5);
    813. cout << tree << endl << "-------------------" << endl;
    814. check(tree.to_string_in_order() == "6 7 8 9 10 ");
    815. tree.erase(6);
    816. cout << tree << endl << "-------------------" << endl;
    817. check(tree.to_string_in_order() == "7 8 9 10 ");
    818. tree.erase(7);
    819. cout << tree << endl << "-------------------" << endl;
    820. check(tree.to_string_in_order() == "8 9 10 ");
    821. tree.erase(8);
    822. cout << tree << endl << "-------------------" << endl;
    823. check(tree.to_string_in_order() == "9 10 ");
    824. tree.erase(9);
    825. cout << tree << endl << "-------------------" << endl;
    826. check(tree.to_string_in_order() == "10 ");
    827. tree.erase(10);
    828. cout << tree << endl << "-------------------" << endl;
    829. check(tree.to_string_in_order() == "");
    830. }
    831. void test20()
    832. {
    833. constexpr int length = 10;
    834. int arr[length] = { 5,3,4,1,2,10,8,9,7,6 };
    835. binary_search_tree<int> tree(arr, length);
    836. cout << tree << endl << "-------------------" << endl;
    837. tree.erase(10);
    838. cout << tree << endl << "-------------------" << endl;
    839. check(tree.to_string_in_order() == "1 2 3 4 5 6 7 8 9 ");
    840. tree.erase(8);
    841. cout << tree << endl << "-------------------" << endl;
    842. check(tree.to_string_in_order() == "1 2 3 4 5 6 7 9 ");
    843. }
    844. void test21()
    845. {
    846. constexpr int length = 10;
    847. int arr[length] = { 5,3,4,1,2,10,8,9,7,6 };
    848. binary_search_tree<int> tree(arr, length);
    849. cout << tree << endl << "-------------------" << endl;
    850. tree.erase(5);
    851. cout << tree << endl << "-------------------" << endl;
    852. check(tree.to_string_in_order() == "1 2 3 4 6 7 8 9 10 ");
    853. }
    854. void test22()
    855. {
    856. constexpr int length = 10;
    857. int arr[length] = { 2,4,6,8,10,1,3,5,7,9 };
    858. binary_search_tree<int> tree(arr, length);
    859. check(tree.hight() == 6);
    860. tree.erase(1);
    861. check(!tree.exists(1));
    862. tree.erase(2);
    863. check(!tree.exists(2));
    864. tree.erase(3);
    865. check(!tree.exists(3));
    866. tree.erase(4);
    867. check(!tree.exists(4));
    868. tree.erase(5);
    869. check(!tree.exists(5));
    870. check(tree.to_string_in_order() == "6 7 8 9 10 ");
    871. tree.erase(6);
    872. check(!tree.exists(6));
    873. tree.erase(7);
    874. check(!tree.exists(7));
    875. tree.erase(8);
    876. check(!tree.exists(8));
    877. tree.erase(9);
    878. check(!tree.exists(9));
    879. tree.erase(10);
    880. check(!tree.exists(10));
    881. check(tree.empty());
    882. }
    883. void test23()
    884. {
    885. //test equal
    886. int a[3] = { 15, 12, 14 };
    887. binary_search_tree<int> tree(a, 3);
    888. check(tree.hight() == 3);
    889. cout << "tree:\n" << tree << endl;
    890. auto tree2 = tree;
    891. cout << "tree2:\n" << tree2 << endl;
    892. check(tree2.equal(tree));
    893. }
    894. void test24(binary_search_tree<int>& tree)
    895. {
    896. cout << "tree:\n" << tree << endl;
    897. auto tree2 = tree;
    898. cout << "tree2:\n" << tree2 << endl;
    899. check(tree2.equal(tree));
    900. check(tree2 == tree);
    901. tree.clear();
    902. cout << tree << endl;
    903. check(tree2.equal(tree) == false);
    904. check(tree2 != tree);
    905. }
    906. void test25()
    907. {
    908. int a[3] = { 15, 12, 14 };
    909. binary_search_tree<int> tree(a, 3);
    910. tree.print_in_order_recursive(cout);
    911. }
    912. int main()
    913. {
    914. test1();//empty
    915. test2();//test create insert empty size
    916. test3();
    917. test4();
    918. test5();
    919. test6();
    920. test7();
    921. test8();
    922. test9();
    923. test10();
    924. test11();
    925. test12();
    926. test13();
    927. test14();//minmum maxmum
    928. test15();
    929. test16();//exists clear erase size empty
    930. test17();//erase
    931. test18();//erase
    932. test19();//erase
    933. test20();//erase
    934. test21();//erase
    935. test22();//erase
    936. test23();
    937. int maxLength = 0;
    938. int a[100] = { 15, 12, 14, 13, 16
    939. , 34, 23, 24, 22, 21
    940. , 20, 19, 18, 17, 35
    941. , 36, 37, 38, 39, 40
    942. , 41, 0 };
    943. binary_search_tree<int> tree(a, 22);
    944. check(tree.size() == 22);
    945. check(tree.empty() == false);
    946. check(tree.maxmum() == 41);
    947. check(tree.minmum() == 0);
    948. test_tree(tree);
    949. binary_search_tree<int> tree1(a, 3);
    950. test_tree(tree1);
    951. test24(tree);//test copy
    952. test25();//print
    953. return 0;
    954. }

    正确输出

    1. line:725 Pass
    2. line:726 Pass
    3. line:727 Pass
    4. line:733 Pass
    5. line:734 Pass
    6. line:735 Pass
    7. line:741 Pass
    8. line:742 Pass
    9. line:743 Pass
    10. line:749 Pass
    11. line:750 Pass
    12. line:751 Pass
    13. line:758 Pass
    14. line:759 Pass
    15. line:760 Pass
    16. line:767 Pass
    17. line:768 Pass
    18. line:769 Pass
    19. line:776 Pass
    20. line:777 Pass
    21. line:778 Pass
    22. line:785 Pass
    23. line:786 Pass
    24. line:787 Pass
    25. line:794 Pass
    26. line:796 Pass
    27. line:797 Pass
    28. line:804 Pass
    29. line:806 Pass
    30. line:807 Pass
    31. line:814 Pass
    32. line:816 Pass
    33. line:817 Pass
    34. line:818 Pass
    35. line:825 Pass
    36. line:827 Pass
    37. line:828 Pass
    38. line:829 Pass
    39. line:836 Pass
    40. line:837 Pass
    41. line:838 Pass
    42. line:845 Pass
    43. line:846 Pass
    44. line:847 Pass
    45. line:854 Pass
    46. line:855 Pass
    47. line:862 Pass
    48. line:864 Pass
    49. line:865 Pass
    50. line:871 Pass
    51. 3
    52. --2
    53. --1
    54. 3
    55. --1
    56. line:875 Pass
    57. line:876 Pass
    58. line:877 Pass
    59. line:878 Pass
    60. line:885 Pass
    61. line:886 Pass
    62. line:888 Pass
    63. line:889 Pass
    64. line:891 Pass
    65. line:892 Pass
    66. line:893 Pass
    67. --10
    68. --9
    69. --8
    70. --7
    71. --6
    72. 5
    73. --4
    74. --3
    75. --2
    76. --1
    77. -------------------
    78. --10
    79. --9
    80. --8
    81. --7
    82. --6
    83. 5
    84. --4
    85. --3
    86. --2
    87. -------------------
    88. line:903 Pass
    89. --10
    90. --9
    91. --8
    92. --7
    93. --6
    94. 5
    95. --4
    96. --3
    97. -------------------
    98. line:906 Pass
    99. line:908 Pass
    100. --10
    101. --9
    102. --8
    103. --7
    104. --6
    105. 5
    106. --4
    107. -------------------
    108. --10
    109. --9
    110. --8
    111. --7
    112. --6
    113. 5
    114. -------------------
    115. line:912 Pass
    116. 10
    117. --9
    118. --8
    119. --7
    120. --6
    121. -------------------
    122. line:915 Pass
    123. 10
    124. --9
    125. --8
    126. --7
    127. -------------------
    128. line:918 Pass
    129. 10
    130. --9
    131. --8
    132. -------------------
    133. line:921 Pass
    134. 10
    135. --9
    136. -------------------
    137. line:924 Pass
    138. 10
    139. -------------------
    140. line:927 Pass
    141. -------------------
    142. line:930 Pass
    143. --10
    144. --9
    145. --8
    146. --7
    147. --6
    148. 5
    149. --4
    150. --3
    151. --2
    152. --1
    153. -------------------
    154. --9
    155. --8
    156. --7
    157. --6
    158. 5
    159. --4
    160. --3
    161. --2
    162. --1
    163. -------------------
    164. line:940 Pass
    165. --9
    166. --7
    167. --6
    168. 5
    169. --4
    170. --3
    171. --2
    172. --1
    173. -------------------
    174. line:943 Pass
    175. --10
    176. --9
    177. --8
    178. --7
    179. --6
    180. 5
    181. --4
    182. --3
    183. --2
    184. --1
    185. -------------------
    186. --10
    187. --9
    188. --8
    189. --7
    190. 6
    191. --4
    192. --3
    193. --2
    194. --1
    195. -------------------
    196. line:953 Pass
    197. line:960 Pass
    198. line:962 Pass
    199. line:964 Pass
    200. line:966 Pass
    201. line:968 Pass
    202. line:970 Pass
    203. line:971 Pass
    204. line:973 Pass
    205. line:975 Pass
    206. line:977 Pass
    207. line:979 Pass
    208. line:981 Pass
    209. line:982 Pass
    210. line:989 Pass
    211. tree:
    212. 15
    213. --14
    214. --12
    215. tree2:
    216. 15
    217. --14
    218. --12
    219. line:993 Pass
    220. line:1047 Pass
    221. line:1048 Pass
    222. line:1049 Pass
    223. line:1050 Pass
    224. test_tree:
    225. --41
    226. --40
    227. --39
    228. --38
    229. --37
    230. --36
    231. --35
    232. --34
    233. --24
    234. --23
    235. --22
    236. --21
    237. --20
    238. --19
    239. --18
    240. --17
    241. --16
    242. 15
    243. --14
    244. --13
    245. --12
    246. --0
    247. tree size : 22
    248. tree max length between node 14
    249. print_in_order_nonrecursive : 0 12 13 14 15 16 17 18 19 20 21 22 23 24 34 35 36 37 38 39 40 41
    250. print_element_order by order: 0 12 13 14 15 16 17 18 19 20 21 22 23 24 34 35 36 37 38 39 40 41
    251. print_post_order_nonrecursive : 0 13 14 12 17 18 19 20 21 22 24 23 41 40 39 38 37 36 35 34 16 15
    252. print_pre_order_nonrecursive : 15 12 0 14 13 16 34 23 22 21 20 19 18 17 24 35 36 37 38 39 40 41
    253. min element : 0
    254. max element : 41
    255. test_tree:
    256. 15
    257. --14
    258. --12
    259. tree size : 3
    260. tree max length between node 2
    261. print_in_order_nonrecursive : 12 14 15
    262. print_element_order by order: 12 14 15
    263. print_post_order_nonrecursive : 14 12 15
    264. print_pre_order_nonrecursive : 15 12 14
    265. min element : 12
    266. max element : 15
    267. tree:
    268. --41
    269. --40
    270. --39
    271. --38
    272. --37
    273. --36
    274. --35
    275. --34
    276. --24
    277. --23
    278. --22
    279. --21
    280. --20
    281. --19
    282. --18
    283. --17
    284. --16
    285. 15
    286. --14
    287. --13
    288. --12
    289. --0
    290. tree2:
    291. --41
    292. --40
    293. --39
    294. --38
    295. --37
    296. --36
    297. --35
    298. --34
    299. --24
    300. --23
    301. --22
    302. --21
    303. --20
    304. --19
    305. --18
    306. --17
    307. --16
    308. 15
    309. --14
    310. --13
    311. --12
    312. --0
    313. line:1000 Pass
    314. line:1001 Pass
    315. line:1004 Pass
    316. line:1005 Pass
    317. 12 14 15 Memory leak report:
    318. No memory leak.
  • 相关阅读:
    Django中的Cookie和Session
    Redis详解(一)
    移动硬盘丢了怎么找回来呢?
    FPGA SPI采集ADC7606数据
    什么是AB实验?能解决什么问题?终于有人讲明白了
    六种常用排序方式详解(C++实现)
    ceph存储系统
    安装虚拟机(VMware)保姆级教程及配置虚拟网络编辑器和安装WindowsServer以及宿主机访问虚拟机和配置服务器环境
    MySQL的日志管理与备份、恢复
    【机器学习笔记】
  • 原文地址:https://blog.csdn.net/ClamReason/article/details/132600649