当前位置:   article > 正文

C++数据结构:二叉排序树_c++代码如何构建一个二叉排序树

c++代码如何构建一个二叉排序树

二叉排序树:

  • 若它的左子树不为空,则左子树上的所有节点的值均小于它的根节点的值
  • 若它的右子树不为空,则右子树上的所有节点的值均大于它的根节点的值
  • 它的左右子树也为二叉排序树

二叉排序树又称二叉查找树,一般使用二叉链表作为二叉排序树的存储结构。 

 二叉排序树结构:

  1. class BST_Node
  2. {
  3. public:
  4. int data;//数据
  5. BST_Node* lchild;//左孩子
  6. BST_Node* rchild;//右孩子
  7. BST_Node(int i=0):data(i),lchild(nullptr),rchild(nullptr){}//构造函数
  8. };
  9. class BSTree
  10. {
  11. public:
  12. BST_Node* tree;
  13. BSTree()
  14. {
  15. tree = nullptr;//初始化
  16. }
  17. };

二叉排序树的查找:(根据数据查找)

  1. 先判断根节点是否为空和判断数据是否相同
  2. 数据大于根节点,那就进入右子树
  3. 数据小于根节点,那就进入左子树

时间复杂度:

  • 最好的情况:O(log2 n)
  • 最坏的情况:O(n)
  1. BST_Node* SeachBST(BST_Node* B,int K)
  2. {
  3. if (!B || B->data == K)//结束条件
  4. {
  5. return B;
  6. }
  7. else if (B->data< K)
  8. {
  9. SeachBST(B->rchild, K);//进入右孩子
  10. }
  11. else
  12. {
  13. SeachBST(B->lchild, K);//进入左孩子
  14. }
  15. }

 

 二叉排序树的插入:

  • 若二叉排序树为空,则插入该节点,使该节点成为根节点、
  • 否则,继续在左子树和右子树中寻找
    • 树中有该数据的话则不插入
    • 树中没有的话,直到找到某个叶子的左子树或右子树为空为止,则插入节点应该为该节点的左孩子或右孩子。
  1. void insert(BST_Node*& B, int K)
  2. {
  3. if (B == nullptr)//如果根节点为空,直接当成根节点
  4. {
  5. B = new BST_Node(K);
  6. return;//结束
  7. }
  8. BST_Node* B1 = B;
  9. BST_Node* P1=nullptr;//获取父节点位置
  10. while (!B1)//寻找插入位置
  11. {
  12. P1 = B1;//保存父节点
  13. if (K < B1->data)
  14. {
  15. B1 = B1->lchild;//如果K小于data,进入左孩子
  16. }
  17. else if(K > B1->data)
  18. {
  19. B1 = B1->rchild;//如果K大于data,进入右孩子
  20. }
  21. else
  22. {
  23. return;//相同的话,不插入,结束
  24. }
  25. }
  26. BST_Node* G = new BST_Node(K);//创建新节点
  27. if (K > P1->data)
  28. {
  29. P1->rchild = G;//作为右孩子
  30. }
  31. else
  32. {
  33. P1->lchild = G;//作为左孩子
  34. }
  35. }

  二叉排序树的删除:

  • 第一种情况:叶子节点,可以直接删除
  • 第二种情况:被删除节点只有左子树或右子树,可以直接把左子树或右子树直接拼接其父节点上
  • 第三种情况:被删除节点既有左子树又有右子树
    • 可以用左子树中的最大值替换该节点,并删除该最大值节点
    • 可以用右子树中的最小值替换该节点,并删除该最小值节点

 

 

 按照以上思路写的代码,可以用查找和判段左右孩子函数来精简该代码。

  1. void Delete(BST_Node*& B, int K)
  2. {
  3. if (B == nullptr) return;//根节点为空,退出
  4. BST_Node* P = B;
  5. BST_Node* F = nullptr;//保存父节点
  6. while (P != nullptr)
  7. {
  8. F = P;
  9. if (P->data > K){
  10. P = P->lchild;//K小于节点数据,进入左孩子
  11. }
  12. else if (P->data < K){
  13. P = P->rchild;//K小于节点数据,进入右孩子
  14. }
  15. else{
  16. break;//找到节点退出循环
  17. }
  18. }
  19. if (P == nullptr)return;//如果没找到的话退出
  20. //查看该节点是否拥有右左子树
  21. if (P->lchild == nullptr && P->rchild == nullptr)// 叶子节点的话
  22. {
  23. if (F->data > P->data)F->lchild = nullptr;
  24. else { F->rchild = nullptr; }
  25. delete P;//释放节点内存
  26. return;
  27. }
  28. if (P->lchild != nullptr && P->rchild != nullptr)//拥有左右子树的话
  29. {
  30. //找到右子树的最小值,在该节点的右子树的左子树中
  31. BST_Node* M = P;//存放当前节点位置
  32. F = P;
  33. P = P->rchild;
  34. while (P->lchild!=nullptr)
  35. {
  36. F = P;
  37. P = P->lchild;//找到最小值
  38. }
  39. M->data = P->data;//数据赋值给节点
  40. F->lchild = nullptr;
  41. delete P;//释放节点内存
  42. return;
  43. }
  44. //单子树的情况
  45. if (P->lchild == nullptr && F->lchild==P)
  46. {
  47. F->lchild = P->rchild;
  48. }
  49. else if (P->lchild == nullptr && F->rchild == P)
  50. {
  51. F->rchild = P->rchild;
  52. }
  53. else if (P->rchild == nullptr && F->lchild == P)
  54. {
  55. F->lchild = P->rchild;
  56. }
  57. else
  58. {
  59. F->rchild = P->rchild;
  60. }
  61. delete P;
  62. }

 

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号