二叉查找树的代码实现

二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉搜索树作为一种经典的数据结构,它既有链表的快速插入与删除操作的特点,又有数组快速查找的优势;所以应用十分广泛,例如在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。

以下是实现代码:

struct Node{
        shared_ptr<Node> left_;
        shared_ptr<Node> right_;
        int value_;
        Node(int v){
            value_ = v;
        }
    };
    class binary_sort_tree{
        // xianxu root left right
        // zhongxu left root right
        // houxu left right root
        public:
        binary_sort_tree(){
            head = nullptr;
        }
        bool insert(int key){
            shared_ptr<Node> cur = make_shared<Node>(key);
            if(!head){
                head = cur;
                return true;
            }
            shared_ptr<Node> n = find(key);
            if(n){
                // update data
                return true;
            }
            insert(head, cur);

            return false;
        }
        bool insert(shared_ptr<Node>n, shared_ptr<Node> cur){
            if(!n || !cur)return false;
            if(cur->value_ <= n->value_){
                if(n->left_ == nullptr){
                    return _insert(n, cur, true);
                }else{
                    return insert(n->left_, cur);
                }
            }else{
                if(n->right_ == nullptr){
                    return _insert(n, cur, false);
                }else{
                    return insert(n->right_, cur);
                }
            }
            return false;
        }
        bool _insert(shared_ptr<Node> n, shared_ptr<Node> cur, bool left){
            if(!n || !cur)
                return false;
            if(left){
                cur->left_ = n->left_;
                n->left_ = cur;
            }else{
                cur->right_ = n->right_;
                n->right_ = cur;
            }
            return true;
        }
        bool erase(int key){
            if(!head){
                return false;
            }
            
            if(head->value_ == key){
                head = _erase(head);
                
                return true;
            }
            return erase(head, key);
        }
        bool erase(shared_ptr<Node> n, int key){
            if(!n)return false;
            if(key< n->value_ && n->left_ ){
                if(n->left_->value_ == key){
                    n->left_ = _erase(n->left_);
                    return true;
                }else{
                    return erase(n->left_, key);
                }
            }
            else if(n->right_ && key > n->value_){
                if(n->right_->value_ == key){
                    n->right_ = _erase(n->right_);
                    return true;
                }else {
                    return erase(n->right_, key);
                }
            }
            return false;
        }
        // 右子节点上升,左子树挂到右子树的左叶子节点
        shared_ptr<Node> _erase(shared_ptr<Node> n){
            if(!n)
                return nullptr;
            if(n->right_){
                shared_ptr<Node> cur = n->right_;
                while(cur){
                    if(!cur->left_)break;
                    cur = cur->left_;
                }
                cur->left_ = n->left_;
                return n->right_;
            }else{
                return n->left_;
            }
            return nullptr;
        }
        shared_ptr<Node> find(int key){
            return find(head, key);
        }
        shared_ptr<Node> find(shared_ptr<Node> n, int key){
            if(!n)return nullptr;
            if(key == n->value_)
                return n;
            if(key > n->value_){
                return find(n->right_, key);
            }else{
                return find(n->left_, key);
            }
        }
        int calc_dep(shared_ptr<Node> n){
            if(!n)return 0;
            if(n->left_ || n->right_){
                return 1+max(calc_dep(n->left_), calc_dep(n->right_));
            }
            return 1;
        }
        void xianxu_print(shared_ptr<Node> n){
            if(!n)return;
            printf("%d\n", n->value_);
            xianxu_print(n->left_);
            xianxu_print(n->right_);
        };    
        void zhongxu_print(shared_ptr<Node> n){
            if(!n)return;
            zhongxu_print(n->left_);
            printf("%d\n", n->value_);
            zhongxu_print(n->right_);
        };   
        void houxu_print(shared_ptr<Node> n){
            if(!n)return;
            houxu_print(n->left_);
            houxu_print(n->right_);
            printf("%d\n", n->value_);
        }; 
        void test(){
            vector<int> v{11,9,7,5,3,1,2,4,6,8,10};
            for(auto it: v){
                insert(it);
            }
            zhongxu_print(head);
            printf("head: %d\n", head->value_);
            printf("dep: %d\n", calc_dep(head));
            erase(10);
            zhongxu_print(head);
            printf("head: %d\n", head->value_);
            printf("dep: %d\n", calc_dep(head));
        }
        shared_ptr<Node> head;
    };

二叉查找树在通常情况下具备O(log(n))的查询效率,但是假如如test中测试用例,生成的树倾斜度非常高。如下图
在这里插入图片描述
最差情况下,所有节点均不在同一层,查询效率会降低到O(n)。

所以,朴素的二叉查找树一般不直接使用,而是结合一些解决平衡的方法,用以效率优化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 C++ 语言实现二叉查找树代码: ```cpp #include <iostream> using namespace std; // 定义二叉查找树节点结构体 struct TreeNode { int val; TreeNode* left; TreeNode* right; TreeNode(int x) : val(x), left(NULL), right(NULL) {} }; // 向二叉查找树中插入节点的函数 TreeNode* insert(TreeNode* root, int val) { if (root == NULL) { return new TreeNode(val); } if (val < root->val) { root->left = insert(root->left, val); } else if (val > root->val) { root->right = insert(root->right, val); } return root; } // 在二叉查找树中查找节点的函数 bool search(TreeNode* root, int val) { if (root == NULL) { return false; } if (root->val == val) { return true; } else if (val < root->val) { return search(root->left, val); } else { return search(root->right, val); } } // 中序遍历二叉查找树 void inorderTraversal(TreeNode* root) { if (root == NULL) { return; } inorderTraversal(root->left); cout << root->val << " "; inorderTraversal(root->right); } int main() { TreeNode* root = NULL; root = insert(root, 5); root = insert(root, 2); root = insert(root, 7); root = insert(root, 1); root = insert(root, 3); root = insert(root, 6); root = insert(root, 8); cout << "Inorder traversal: "; inorderTraversal(root); cout << endl; int val = 3; cout << "Search " << val << ": " << (search(root, val) ? "Found" : "Not found") << endl; val = 4; cout << "Search " << val << ": " << (search(root, val) ? "Found" : "Not found") << endl; return 0; } ``` 这段代码中,我们首先定义了二叉查找树节点的结构体 `TreeNode`,包含一个 `val` 表示节点值,以及两个指针 `left` 和 `right` 分别表示左右子节点。 接着,我们实现了两个函数:`insert` 和 `search`。`insert` 函数用于向二叉查找树中插入节点,如果当前节点为空,则新建一个节点,并返回该节点作为新的子节点;如果待插入节点值小于当前节点,则继续在当前节点的左子树中插入;否则,在当前节点的右子树中插入。 `search` 函数用于在二叉查找树中查找节点,如果当前节点为空,则直接返回 false;如果当前节点的值等于待查找值,则返回 true;否则,如果待查找值小于当前节点,则在左子树中继续查找;否则,在右子树中继续查找。 最后,我们实现了中序遍历二叉查找树的函数 `inorderTraversal`,以及一个简单的 `main` 函数,用于测试插入和查找节点的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值