提示信息

C++二叉搜索树(BST)详细介绍

专属 已关注

二叉搜索树(Binary Search Tree,简称BST)是一种特殊的二叉树数据结构,对树中的每个节点都有以下性质:

  1. 节点结构:每个节点包含三个属性:键(或值)、左子节点和右子节点。有些实现中,每个节点还会包含指向其父节点的指针。

  2. 左子树性质:对于每个节点,其左子树的所有节点的键值都小于该节点的键值。

  3. 右子树性质:对于每个节点,其右子树的所有节点的键值都大于该节点的键值。

  4. 递归性质:左子树和右子树也都是二叉搜索树。

基本操作

下面是一些关键的操作及其简单描述:

  1. 插入(Insert)

    • 从根节点开始,比较要插入的值与当前节点的值。
    • 如果要插入的值小于当前节点的值,移动到左子节点;如果大于当前节点值,移动到右子节点。
    • 在找到的空位置插入新的节点。
  2. 查找(Search)

    • 从根节点开始,比较要查找的值与当前节点的值。
    • 如果值等于当前节点的值,表示查找成功。
    • 如果值小于当前节点的值,递归地查找左子树;如果大于,查找右子树。
  3. 删除(Delete)

    • 删除节点时需要考虑三种情况:
      1. 要删除的节点是叶节点:直接删除。
      2. 要删除的节点只有一个子节点:将其子节点替代被删除节点的位置。
      3. 要删除的节点有两个子节点:找到节点的中序后继(即右子树中的最小节点),用中序后继节点的值替换要删除的节点,然后删除中序后继节点。
  4. 遍历(Traversal)

    • 中序遍历(In-order Traversal):左-根-右,得到递增顺序的节点值。
    • 先序遍历(Pre-order Traversal):根-左-右。
    • 后序遍历(Post-order Traversal):左-右-根。

代码示例

下面的示例代码演示了C++中如何实现一个简单的二叉搜索树,以及基本操作:

  1. #include <iostream>
  2. struct TreeNode {
  3. int value;
  4. TreeNode *left, *right;
  5. TreeNode(int val) : value(val), left(nullptr), right(nullptr) {}
  6. };
  7. class BST {
  8. public:
  9. TreeNode* insert(TreeNode* root, int val) {
  10. if (!root) return new TreeNode(val);
  11. if (val < root->value)
  12. root->left = insert(root->left, val);
  13. else if (val > root->value)
  14. root->right = insert(root->right, val);
  15. return root;
  16. }
  17. bool search(TreeNode* root, int val) {
  18. if (!root) return false;
  19. if (val == root->value)
  20. return true;
  21. else if (val < root->value)
  22. return search(root->left, val);
  23. else
  24. return search(root->right, val);
  25. }
  26. TreeNode* findMin(TreeNode* root) {
  27. while (root->left) root = root->left;
  28. return root;
  29. }
  30. TreeNode* deleteNode(TreeNode* root, int val) {
  31. if (!root) return root;
  32. if (val < root->value)
  33. root->left = deleteNode(root->left, val);
  34. else if (val > root->value)
  35. root->right = deleteNode(root->right, val);
  36. else {
  37. if (!root->left) {
  38. TreeNode* temp = root->right;
  39. delete root;
  40. return temp;
  41. } else if (!root->right) {
  42. TreeNode* temp = root->left;
  43. delete root;
  44. return temp;
  45. }
  46. TreeNode* temp = findMin(root->right);
  47. root->value = temp->value;
  48. root->right = deleteNode(root->right, temp->value);
  49. }
  50. return root;
  51. }
  52. void inorderTraversal(TreeNode* root) {
  53. if (!root) return;
  54. inorderTraversal(root->left);
  55. std::cout << root->value << " ";
  56. inorderTraversal(root->right);
  57. }
  58. };
  59. int main() {
  60. BST tree;
  61. TreeNode* root = nullptr;
  62. root = tree.insert(root, 50);
  63. root = tree.insert(root, 30);
  64. root = tree.insert(root, 70);
  65. root = tree.insert(root, 20);
  66. root = tree.insert(root, 40);
  67. root = tree.insert(root, 60);
  68. root = tree.insert(root, 80);
  69. std::cout << "Inorder traversal: ";
  70. tree.inorderTraversal(root);
  71. std::cout << std::endl;
  72. std::cout << "Search 40: " << (tree.search(root, 40) ? "Found" : "Not Found") << std::endl;
  73. root = tree.deleteNode(root, 30);
  74. std::cout << "Inorder traversal after deleting 30: ";
  75. tree.inorderTraversal(root);
  76. std::cout << std::endl;
  77. return 0;
  78. }

性能

  1. 时间复杂度

    • 平均情况下,查找、插入和删除的时间复杂度为O(log n),其中n是树中的节点数。
    • 在最坏情况下(当树退化成链表),时间复杂度变为O(n)。
  2. 空间复杂度

    • 空间复杂度主要是存储树的节点,通常为O(n)。

通过自平衡二叉搜索树(例如AVL树、红黑树),可以避免最坏情况下的性能退化,确保时间复杂度保持在O(log n)。

    遇到难题? "AI大模型GPT4.0、GPT" 是你的私人解答专家! 点击按钮去提问......
专属 关注 已关注

最近一次登录:2024-11-19 21:35:54   

暂时还没有签名,请关注我或评论我的文章
×
免费图表工具,画流程图、架构图