当前位置:   article > 正文

C++ 二叉搜索树原理及其实现

二叉搜索树的原理c++

首先是概念:
二叉搜索树又称二叉排序树,它具有以下的性质:

  • 若是左子树不为空,则左子树上所有节点的值小于根节点的值
  • 若是右子树不为空,则右子树上所有结点的值大于根节点的值
  • 二叉搜索树的左右子树也是二叉搜索树
  • 二叉搜索树的中序排列是一个有序数列

再下来是它的实现

首先是构造节点:

  1. template<class K>
  2. struct BStreeNode{
  3. BStreeNode(const K& date = K()) //节点的定义
  4. :leftC(nullptr), // 初始化
  5. rightC(nullptr),
  6. date_(date)
  7. {}
  8. BStreeNode<K> *leftC; //左孩子
  9. BStreeNode<K> *rightC; //右孩子
  10. K date_;
  11. };

二叉搜索树类的实现:

  1. template<class K>
  2. class BStree{
  3. typedef BStreeNode<K> BsNode;
  4. public:
  5. BStree() :
  6. _root(nullptr)
  7. {}
  8. BsNode* Find(const K& date){ //查找节点
  9. BsNode* pNode = _root;
  10. while (pNode){
  11. if (pNode->date_ == date){
  12. return pNode;
  13. }
  14. else if (pNode->date_ > date){
  15. pNode = pNode->rightC;
  16. }
  17. else
  18. pNode = pNode->leftC;
  19. }
  20. return nullptr;
  21. }
  22. bool Insert(const K& date){
  23. BsNode *pNode = _root;
  24. BsNode *parent=nullptr;
  25. if (_root == nullptr){ //空树时开辟空间定义为根节点
  26. _root = new BsNode(date);
  27. return true;
  28. }
  29. else if (Find(date)){ //存在相同结点不进行插入
  30. return false;
  31. }
  32. else{
  33. while (pNode){ //找到插入位置,但是这里循环结束后只确认了父母结点,是做左孩子还是右孩子不确认( 因为此时值为nullptr )
  34. parent = pNode;
  35. if (pNode->date_ > date){
  36. pNode = pNode->leftC;
  37. }
  38. else{
  39. pNode = pNode->rightC;
  40. }
  41. }
  42. pNode = new BsNode(date); //构造结点
  43. if (parent->date_ > date){ //确认是做左孩子还是右孩子
  44. parent->leftC = pNode;
  45. }
  46. else{
  47. parent->rightC = pNode;
  48. }
  49. return true;
  50. }
  51. }
  52. bool Delete(const K& date){
  53. BsNode *pNode = _root;
  54. BsNode *parent = nullptr;
  55. if (pNode == nullptr){ //空树情况
  56. return false;
  57. }
  58. while (pNode){ //找到要删除的结点
  59. if (pNode->date_ == date){
  60. break;
  61. }
  62. else if (pNode->date_ < date){
  63. parent = pNode;
  64. pNode = pNode->rightC;
  65. }
  66. else{
  67. parent = pNode;
  68. pNode = pNode->leftC;
  69. }
  70. }
  71. //BsNode *pdel=pNode;
  72. if (pNode == parent){ //要删除的点是根节点
  73. if (pNode->leftC){
  74. pNode = pNode->leftC;
  75. }
  76. else if (pNode->rightC){
  77. pNode = pNode->rightC;
  78. }
  79. else{
  80. pNode = nullptr;
  81. }
  82. }
  83. if (pNode == nullptr){ // 没有找到要删除的节点
  84. return false;
  85. }
  86. if (pNode->rightC && pNode->leftC == nullptr){ //结点只有右子树
  87. if (pNode == parent->leftC){
  88. parent->leftC = pNode->rightC;
  89. }
  90. else{
  91. parent->rightC = pNode->rightC;
  92. }
  93. }
  94. else if (pNode->leftC && pNode->rightC == nullptr){ //结点只有左子树
  95. if (pNode == parent->leftC){
  96. parent->leftC = pNode->leftC;
  97. }
  98. else{
  99. parent->rightC = pNode->leftC;
  100. }
  101. }
  102. else if (pNode->leftC && pNode->rightC){ //儿女俱全
  103. if (pNode == parent->leftC){ //要删除的节点是父母节点的左孩子,删除后的位置要由原先节点的右孩子替代
  104. pNode->rightC->leftC = pNode->leftC;
  105. parent->leftC = pNode->rightC;
  106. }
  107. else{
  108. pNode->leftC->rightC= pNode->rightC; //要删除的节点是父母节点的右孩子,删除后的位置要由原先节点的左孩子替代
  109. parent->rightC = pNode->leftC;
  110. }
  111. }
  112. else{ //无子可依
  113. if (pNode == parent->leftC){
  114. parent->leftC = nullptr;
  115. }
  116. else{
  117. parent->rightC = nullptr;
  118. }
  119. }
  120. delete pNode; //在连接完成后最后再进行删除
  121. return true;
  122. }
  123. BsNode* IfLeftMost(){
  124. if (_root == nullptr){
  125. return nullptr;
  126. }
  127. BsNode *pNode = _root;
  128. while (pNode->leftC){
  129. pNode = pNode->leftC;
  130. }
  131. return pNode;
  132. }
  133. BsNode* IfRightMost(){
  134. if (_root == nullptr){
  135. return nullptr;
  136. }
  137. BsNode *pNode = _root;
  138. while (pNode->rightC){
  139. pNode = pNode->rightC;
  140. }
  141. return pNode;
  142. }
  143. void InOrder(){ //定义一个借口给外部调用,因为根节点在这里是private权限
  144. InOrder(_root);
  145. cout << endl;
  146. }
  147. private:
  148. void InOrder(BsNode *pNode){ //二叉树的中序遍历,用来检查结果(二叉搜索树中序遍历应该是一个有序序列)
  149. if (pNode){
  150. InOrder(pNode->leftC);
  151. cout << pNode->date_ << ' ';
  152. InOrder(pNode->rightC);
  153. }
  154. }
  155. private:
  156. BsNode *_root;
  157. };

测试函数这里就不提供了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/533197
推荐阅读
相关标签
  

闽ICP备14008679号