[C++] 实现二叉搜索树

5 篇文章 0 订阅

摘要

在学STL的关联容器的时候,遇到了一些树,这里把它实现一下

BST

Win QT + MinGW 5.4 + C++11

#include <QCoreApplication>

#include <iostream>
#include <vector>
using namespace std;

// 这里只实现int Tree, 对于泛型T需要用到Traits
namespace WY_Tree{
    struct Tree{

    private:
        vector<int> *v = nullptr;
        const int MAX_INT = 999999;
        const int zwf = 999998; //占位符
        enum _Tree_Type{
            original,
            BST
        };

    public:
        _Tree_Type Tree_Type=original;

    private:

        /* 构造一个基础树 */
        vector<int>* new_tree(){
            vector<int> *new_t = new vector<int>();
            new_t->push_back(MAX_INT);
            return new_t;
        }

        /* 获取当前节点的父亲节点的index */
        int father(const int& index){
            if(0==index || 1==index){
                return index;
            }
            else{
                return index>>1;
            }
        }

        int left_child(const int& index){
            if(0==index){
                return index;
            }
            return index<<1;
        }

        int right_child(const int& index){
            if(0==index){
                return index;
            }
            return (index<<1) + 1;
        }

    public:

        /*
         * 重构当前树为二叉搜索树
         * 注意:占位符 zwf 不能出现在树中
         */
        void make_BST(){
            if(this->v == nullptr){
                cout<<"Error: (1000) Current tree has no content"<<endl;
                return ;
            }

            vector<int> *new_t = WY_Tree::Tree::new_tree();
            vector<int> *old_t = WY_Tree::Tree::new_tree();

            /* 将原始树还原到没有占位符的状态 */
            for(auto itr = this->v->begin()+1; itr!=this->v->end(); ++itr){
                if(*itr!=zwf){
                    old_t->push_back(*itr);
                }
            }

            /* 从旧数组中逐个取出元素插入到新的BST中去 */
            int old_size = old_t->size();
            for(int i=1; i<old_size; ++i){
                int new_value = old_t->at(i);
                int cur_size = new_t->size();
                int cur_index = 1; //从root开始


                while(1){

                    /* 如果待插入位置越界,则往vector插入zwf占位*/
                    if(cur_index>=cur_size){
                        int distance = cur_index-cur_size+1;
                        for(int j=0; j<distance; ++j){
                            new_t->push_back(zwf);
                        }
                    }

                    if(new_t->at(cur_index) == zwf){
                        (*new_t)[cur_index] = new_value;
                        break;
                    }
                    else if(new_t->at(cur_index) >= new_value){
                        cur_index = this->left_child(cur_index);
                    }
                    else{
                        cur_index = this->right_child(cur_index);
                    }
                }
            }

            /* 将重构后的BST绑定到类中 */
            delete this->v;
            delete old_t;
            this->v = new_t;
            this->Tree_Type = BST;
        }

        int search_BST(const int& target){
            if(this->Tree_Type != BST){
                return 0;
            }
            int cur_index = 1;
            auto cur_tree = this->v;
            int itr_count = 0;
            while(1){
                /* 越界 */
                if(cur_index >= cur_tree->size()){
                    cout<<"Cannot find: "<<target<<endl;
                    return 0;
                }

                ++itr_count;
                int cur_value = cur_tree->at(cur_index);
                if( cur_value==zwf ){
                    cout<<"Cannot find: "<<target<<endl;
                    return 0;
                }
                else if( target < cur_value ){
                    cur_index = this->left_child(cur_index);
                }
                else if( target > cur_value){
                    cur_index = this->right_child(cur_index);
                }
                else{
                    cout<<"Found: "<<target<<" at index of "<<cur_index<<" in "<<itr_count<<" iterations "<<endl;
                    return itr_count;
                }
            }
        }


        /* 打印当前树 */
        void print(){
            if(this->v->empty()){
                cout<<"The Tree is Empty"<<endl;
            }
            for(auto itr = (this->v->begin()+1); itr!= this->v->end(); itr++){
                if((*itr)==zwf){
                    cout<<0<<" ";
                }else{
                    cout<<(*itr)<<" ";
                }
            }
            cout<<endl;
        }


    public:
        Tree(){
            this->v = WY_Tree::Tree::new_tree();
        };
        Tree(const vector<int>& new_v){
            this->v = WY_Tree::Tree::new_tree();
            for(int i=0; i<new_v.size(); ++i){
                this->v->push_back(new_v.at(i));
            }
        }
        ~Tree(){
            if(this->v!=nullptr) {
                delete this->v;
            }
        }
    };
}


int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    vector<int> v{17,12,19,10,15,18,25,8,11,13,16,26};
    WY_Tree::Tree t(v); 
    t.make_BST(); //构造一棵BST
    t.print();

    double BST_Average_Iterations = 0;
    for(auto itr=v.begin(); itr!=v.end(); ++itr){
        BST_Average_Iterations+=t.search_BST(*itr);
    }
    cout<<"Average Iterations BST : "<<BST_Average_Iterations/v.size()<<endl;

    return a.exec();
}

结果

这里简单的计算了搜索vector中所有数字的平均次数

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值