二叉搜索树

二分搜索树结构

每个节点都是一个结构体, 由Key-Value 一对
规定:
1,左子树的所有节点的 key 小于根节点的key
2,右子树的所有节点的 key 大于根节点的key

在这两个规定下就可以构建一棵二查搜索树
简单用c++的一个类来构建一棵二叉搜索树
实现功能
统计圣经里面所有单词的词频,把单词存入Key中,在value中记录单词出现的次数

  1. size();返回节点数量
  2. isEmpth();返回树是否为空
  3. insetr();插入一个节点(单词),或者更新单词的数量也就是value的值++
  4. contain();是否有这个key存在
  5. searck();返回key对应的value
  6. minimun();返回Key的最小值
  7. maxmnm();返回key的最大值
  8. perOeder();前序遍历
  9. inOrder();终须遍历
  10. PostOrder();后序遍历
  11. afterlOrder();广都遍历
  12. remoceMax()删除key最大的值
  13. removeMin()删除后Key最小的值
  14. remove() 删除给定的Key值
  15. 还有四个方法没事实现等以后了在说

    template < typename Key, typename Value >
    class BST2 
    {
        struct Node
        {
            Key key;
            Value value;
            Node *left;
            Node *right;
            int count;
            Node(Key key,Value value){
                this->key = key;
                this->value = value;
                this->count = 1;
                this->left = this->right = NULL;
            }
            Node(Node *node) 
            {
                this->key =node->key;
                this->value =node->value;
                this->count = node->count;
                this->left = node->left;
                this->right = node->right;
            }
        };
        Node *root;
        int count=0;
    public:
        BST2() {};
        ~BST2() {};
        int size() { return count; }
        bool isEmpth() { return count == 0 ? false : true; }
        //插入节点
        void insert(Key key, Value value) 
        {
            root = insert(root, key, value);
        }
        Node *insert(Node* node, Key key, Value value)
        {
            if (node == NULL)
            {
                count++;
                return node = new Node(key, value);
            }
            node->count++;
            if (key == node->key) 
            { 
                node->value = node->value + 1;
                count--; 
                return node; 
            }
            if (key < node->key)
                //insert(node->left, key, value);
                node->left = insert(node->left, key, value);
            else
                //insert(node->right, key, value);
                node->right = insert(node->right, key, value);
            return node;
        }
        //是否有这个节点
        bool contain(Key key)
        {
            if (root == NULL) return false;
            else return contain(root,key);
        }
        bool contain(Node* node, Key key)
        {
            if (node == NULL) return false;
            if (node->key == key)
                return true;
            if (key < node->key)
                return contain(node->left, key);
            else 
                return contain(node->right, key);
        }
        //返回查找的Key对应的value
        Value* search(Key key) 
        {
            if (contain(key) == true)
                return search(root, key);
            else return NULL;
        }
        Value* search(Node* node, Key key)
        {
            if (key == node->key)
                return &(node->value);
            if (key > node->key)
                return search(node->right, key);
            else
                return search(node->left, key);
        }
        //返回最小值最大值
        Node* minimum()
        {
            if (root != NULL)
                return minimum(root);
            else
                return NULL;
        }
        Node* minimum(Node* node)
        {
            if (node->left != NULL)
                return minimum(node->left);
            else
                return node;
        }
        Node* maximnm()
        {
            if (root != NULL)
                return minimum(root);
            else
                return NULL;
        }
        Node* maximnm(Node* node)
        {
            if (node->right != NULL)
                return minimum(node->right);
            else
                return node;
        }
        //四种遍历 前中后深度遍历  后序遍历
        void preOrder() 
        {
            if (root) preOrder(root);
        }
        void preOrder(Node *node)
        {
            cout << node->key << " " << node->value << " " << node->count << endl;
            if (node->left != NULL)
                preOrder(node->left);
            if (node->right != NULL)
                preOrder(node->right);
        }
        void inOrder() 
        {
            if (root) inOrder(root);
        }
        void inOrder(Node *node)
        {
            if (node->left != NULL)
                inOrder(node->left);
            cout << node->key << " " << node->value << " " << node->count << endl;
            if (node->right != NULL)
                inOrder(node->right);
        }
        void postOrder() 
        {
            if (root) postOrder(root);
        }
        void postOrder(Node *node)
        {
            if(node->left  != NULL)
                postOrder(node->left);
            if(node->right !=NULL)
                postOrder(node->right);
            cout << node->key << " " << node->value<<" "<<node->count << endl;
        }

        void afterlOrder() 
        {
            if (root == NULL) return;
            Node* n;
            queue<Node* > q;
            q.push(root);
            while (q.size()!=0)
            {
                n = q.front();
                cout << n->key << " " << n->value<<" "<<n->count << endl;
                if (n->left!=NULL)
                    q.push(n->left);
                if(n->right!=NULL)
                q.push(n->right);
                q.pop();
            }
        }
        //三种删除
        void removeMin() 
        {
            root = removeMin(root);
        }
        Node* removeMin(Node *node)
        {
            if (node->left != NULL)
                node->left = removeMin(node->left);
            else
            {
                delete node;
                count--;
                return NULL;
            }
            (node->count)--;
            return node;
        }
        void removeMax() 
        {
            root = removeMax(root);
        }
        Node* removeMax(Node* node)
        {
            if (node->right != NULL)
                node->right = removeMax(node -> right);
            else
            {
                delete node;
                count--;
                return NULL;
            }
            (node->count)--;
            return node;
        }
        void remove(Key key) 
        {
            if(contain(key)!=false && root!=0)
                root = remove(root, key);
        }
        Node* remove(Node* node, Key key)
        {
            (node->count)--;
            //cout<<"count="<<node->count<<endl;
            if (node == NULL)
                return NULL;
            if (key < node->key)
                node->left = remove(node->left, key);
            else if (key > node->key)
                node->right = remove(node->right, key);
            else if(node->key == key)
            {
                if (node->left == NULL && node->right == NULL)
                {
                    delete node;
                    count--;
                    return NULL;
                }
                if (node->left == NULL)
                {
                    Node* nl = node->right;
                    delete node;
                    count--;
                    return nl;
                }
                if (node->right == NULL)
                {
                    Node* nr = node->left;
                    delete node;
                    count--;
                    return nr;
                }
                //寻找右子树最小的值
                Node *delNode = node;
                Node *newNode = new Node( minimum(node->right) );
                if (newNode = node->right)
                {
                    newNode->count = node->count - 1;
                    newNode->left = node->left;
                    delete node;
                    count--;
                    return newNode;
                }
                else 
                {
                    newNode->left = node->left;
                    newNode->right = node->right;
                    removeMin(node->right);
                    newNode->count = node->count;
                    count--;
                    return newNode;
                }
                //Node *minNode = 
                //newNode = new Node(minNode->key, minNode->value);
                //newNode->left = minNode->left;
                //newNode->right = minNode->right;
                //newNode->count = minNode->count;
                count++;
                removeMin(newNode);
                newNode->right = node->right;
                newNode->left = node->left;
                delete delNode;
                count--;
                return newNode;
            }
            return node;
        }
        //顺序性value前一个元素和后一个元素
        Value* successor(Key key){}
        Value* predecessor(Key key) {}
        //一个不存在树中的元素Key 的距离最近的值
        Value* floor(Key key) {}
        Value* ceil(Key key) {}
        //index是排名第几的元素
        int rank(Key key) {}
        //排名第index的元素是谁
        Value* select(int index) {}

    };

读取文件,我这里直接读取了圣经英文版全文



    int test()
    {
        vector<string> words;
        duqu("D://圣经英文版.txt", words);
        cout << "总共有单词" << words.size() << endl;
        int size = words.size();
        BST2<string, int> s;
        cout << "正在构建树" << endl;

        clock_t startTime = clock();
        for (int i = 0; i < size; i++)
        {
            //cout << "在树中插入第" << i << "个单词  "<< words[i] << endl;
            s.insert(words[i], 1);
        }
        clock_t endTime = clock();
        cout << "构建树所用的时间" << double(endTime - startTime) / CLOCKS_PER_SEC << " S" << endl;
        cout << "构建完成,树中共有节点  " << s.size() << endl;
        s.maximnm();
        cout << "输入想要查找出现次数的单词" << endl;
        while (0)
        {
            string a;
            cin >> a;
            startTime = clock();
            int* b;
            if (s.contain(a) == true)
            {
                cout << "有这个单词" << endl;
                b = s.search(a);
                cout << *b << endl;
            }
            else
                cout << "没有这个单词" << endl;
            endTime = clock();
            cout << "二分搜索树查找需要用时间  " << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
            startTime = clock();
            int x = count(words.begin(), words.end(), a);
            endTime = clock();
            cout << "vector的count方法查找有 " << x << "个 用时" << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
        }

    }

在附上简单的测试代码,可以自己运行测试

    int test()
    {
        vector<string> words;
        duqu("D://test.txt", words);
        cout << "总共有单词" << words.size() << endl;
        int size = words.size();
        BST2<string, int> s;
        cout << "正在构建树" << endl;

        clock_t startTime = clock();
        for (int i = 0; i < size; i++)
        {
            //cout << "在树中插入第" << i << "个单词  "<< words[i] << endl;
            s.insert(words[i], 1);
        }
        clock_t endTime = clock();
        cout << "构建树所用的时间" << double(endTime - startTime) / CLOCKS_PER_SEC << " S" << endl;
        cout << "构建完成,树中共有节点  " << s.size() << endl;
        s.maximnm();
        cout << "输入想要查找出现次数的单词" << endl;
        while (1)
        {
            string a;
            cin >> a;
            startTime = clock();
            int* b;
            if (s.contain(a) == true)
            {
                cout << "有这个单词" << endl;
                b = s.search(a);
                cout << *b << endl;
            }
            else
                cout << "没有这个单词" << endl;
            endTime = clock();
            cout << "二分搜索树查找需要用时间  " << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
            startTime = clock();
            int x = count(words.begin(), words.end(), a);
            endTime = clock();
            cout << "vector的count方法查找有 " << x << "个 用时" << double(endTime - startTime) / CLOCKS_PER_SEC << "S" << endl;
        }
        return 0;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值