二叉查找树的代码实现

二叉查找树(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)。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值