How to implement a binary search tree using C++

A binary search tree is a data structure based on binary search, which has the ability to quickly find, insert and delete elements. In C++, a class can be used to implement a binary search tree whose nodes contain pointers to left and right child nodes and data values. The following describes how to implement a binary search tree in C++.

  1. define node

Class that defines a binary search tree node. Each node needs to save a value, left and right child node pointers:

class Node {
public:
    int value;
    Node* left;
    Node* right;

    Node(int v) {
        value = v;
        left = nullptr;
        right = nullptr;
    }
};
  1. Implements a binary search tree class

Class that defines a binary search tree. It needs to contain a root node pointer and some public functions such as insert, find, delete and traverse.

class BinarySearchTree {
public:
    Node* root;

    BinarySearchTree() {
        root = nullptr;
    }

    Node* insert(int value) {
        if (root == nullptr) {
            root = new Node(value);
            return root;
        } else {
            return insert(root, value);
        }
    }

    Node* insert(Node* node, int value) {
        if (node == nullptr) {
            node = new Node(value);
        } else if (value < node->value) {
            node->left = insert(node->left, value);
        } else if (value > node->value) {
            node->right = insert(node->right, value);
        }
        return node;
    }

    Node* search(int value) {
        return search(root, value);
    }

    Node* search(Node* node, int value) {
        if (node == nullptr || node->value == value) {
            return node;
        } else if (value < node->value) {
            return search(node->left, value);
        } else {
            return search(node->right, value);
        }
    }

    void remove(int value) {
        root = remove(root, value);
    }

    Node* remove(Node* node, int value) {
        if (node == nullptr) {
            return node;
        } else if (value < node->value) {
            node->left = remove(node->left, value);
        } else if (value > node->value) {
            node->right = remove(node->right, value);
        } else {
            if (node->left == nullptr) {
                Node* temp = node->right;
                delete node;
                return temp;
            } else if (node->right == nullptr) {
                Node* temp = node->left;
                delete node;
                return temp;
            }
            Node* successor = getMinNode(node->right);
            node->value = successor->value;
            node->right = remove(node->right, successor->value);
        }
        return node;
    }

    Node* getMinNode(Node* node) {
        while (node->left != nullptr) {
            node = node->left;
        }
        return node;
    }

    void inorderTraversal() {
        inorderTraversal(root);
    }

    void inorderTraversal(Node* node) {
        if (node != nullptr) {
            inorderTraversal(node->left);
            std::cout << node->value << " ";
            inorderTraversal(node->right);
        }
    }
};
  1. Test binary search tree

Test a binary search tree with some test cases:

int main() {
    BinarySearchTree bst;

    // Insert nodes
    bst.insert(5);
    bst.insert(3);
    bst.insert(7);
    bst.insert(1);
    bst.insert(9);

    // Search nodes
    Node* node = nullptr;
    node = bst.search(3);
    if (node) std::cout << "Found: " << node->value << std::endl;

    // Remove nodes
    bst.remove(3);

    // Traverse nodes
    std::cout << "Inorder traversal: ";
    bst.inorderTraversal();
    std::cout << std::endl;

    return 0;
}

output:

Found: 3
Inorder traversal: 1 5 7 9

Through the above implementation, we can easily use C++ to implement a binary search tree and perform insertion, search, deletion and traversal operations on it.

We can further explore the properties of binary search trees. It has the following properties:

  1. The values ​​of all nodes in the left subtree are less than the value of the root node.

  2. The values ​​of all nodes in the right subtree are greater than the value of the root node.

  3. The left and right subtrees themselves are also binary search trees.

It can be seen that, through this property, the binary search tree can quickly locate the position of insertion, search and deletion operations, thereby ensuring high efficiency. At the same time, by traversing the binary search tree, the elements in the ordered output tree can also be realized.

However, the properties of binary search trees are not very suitable for some specific situations. For example, if the inserted data is ordered, the binary search tree will degenerate into a linked list, losing its original advantages. To solve this problem, balanced binary trees (such as AVL trees and red-black trees) can be used to ensure that the height of the tree is balanced, so that its properties are better maintained.

In short, as a basic data structure, the binary search tree has a simple and clear implementation in C++, and its nature makes it the cornerstone of many algorithms.

In addition to basic operations such as insertion, search, and deletion, we can also obtain the values ​​​​of all nodes by traversing the binary search tree. In general, there are three main traversal methods:

1. In-order traversal: first traverse the left subtree, then output the root node, and finally traverse the right subtree.

2. Preorder traversal: first output the root node, then traverse the left subtree, and finally traverse the right subtree.

3. Post-order traversal: first traverse the left subtree, then traverse the right subtree, and finally output the root node.

These three traversal methods have different applications in different situations. For example, in-order traversal can output the elements in the binary search tree in ascending order, and pre-order traversal can be used to recursively create a binary tree.

In addition, we can also use the properties of the binary search tree to implement some other algorithms, such as finding the Kth smallest/largest element, calculating the height of the tree, judging whether it is balanced, etc. The implementation of these algorithms is based on an in-depth understanding of binary search trees, so for C++ programmers, it is very necessary to master the principles and implementation methods of binary search trees.

In conclusion, implementing a binary search tree is a fundamental skill for C++ programmers, and it is the basis for other more complex data structures and algorithms. Therefore, we need to continue to learn and practice, and constantly improve our algorithm and data structure capabilities.

Guess you like

Origin blog.csdn.net/YT21198/article/details/131176287