• treap(堆树)


    # 2018-09-27 17:35:58 我实现的这个treap不能算是堆。有问题

      最近对堆这种结构有点感兴趣,然后想用指针的方式实现一个堆而不是利用数组这种结构,于是自己想到了一个用二叉树结构实现堆的算法,下面是主要操作的源码:

      头文件:

    #ifndef _HEAP_H__
    #define _HEAP_H__
    
    #include <iostream>
    #include <vector>
    
    template<class type>
    class BaseNode {
    private:
    	type val;
    	BaseNode *left, *right;
    public:
    	BaseNode() {}
    	BaseNode(type v) : val(v), left(nullptr), right(nullptr) {}
    	/**/
    	void value(type val) { this->val = val; }
    	void lchild(BaseNode *left) { this->left = left; }
    	void rchild(BaseNode *right) { this->right = right; }
    	type value() { return val; }
    	BaseNode* lchild() { return left; }
    	BaseNode* rchild() { return right; }
    };
    
    template<class type>
    class treap : protected BaseNode<type> {
    	BaseNode<type> *root;
    	size_t count;
    public:
    	treap() : root(nullptr), count(0) {}
    	treap(std::vector<type> iter_type_vec) {
    		for (int i = 0; i < iter_type_vec.size(); i++)
    			insert(iter_type_vec[i]);
    	}
    	~treap() {
    		delete root;
    	}
    	bool empty() const {
    		if (count == 0)
    			return true;
    		return false;
    	}
    	size_t size() const {
    		return count;
    	}
    	type top() const {
    		if (empty())
    		{
    			std::cout << "Underflow!" << std::endl;
    			return -1;
    		}
    		return root->value();
    	}
    	void show() const {
    		travel(root);
    		std::cout << std::endl;
    	};
    	void insert(type val);
    	void remove();
    	void travel(BaseNode<type> *pr) const;
    };
    
    #endif // _HEAP_H__
    

      定义函数的实现:

    #include "Heap.h"
    
    template<class type>
    void treap<type>::insert(type val)
    {
    	BaseNode<type> *node = new BaseNode<type>(val);
    	if (!root)
    		root = node;
    	else if (root->value() <= val)
    	{
    		node->lchild(root);
    		root = node;
    	}
    	else
    	{
    		if (root->lchild() && root->rchild()) {
    			BaseNode<type> *pr = root;
    			while (pr) {
    				if (pr->lchild() && pr->lchild()->value() > val)
    					pr = pr->lchild();
    				else if (pr->rchild() && pr->rchild()->value() > val)
    					pr = pr->rchild();
    				else
    					break;
    			}
    			if (!pr->lchild())
    				pr->lchild(node);
    			else if (!pr->rchild())
    				pr->rchild(node);
    			else {
    				BaseNode<type> *tem = pr->lchild();
    				pr->lchild(node);
    				node->lchild(tem);
    			}
    		}
    		else if (!root->lchild())
    			root->lchild(node);
    		else
    			root->rchild(node);
    	}
    	++count;
    }
    
    template<class type>
    void treap<type>::remove()
    {
    	if (!empty())
    	{
    		if (root->lchild() && root->rchild())
    		{
    			if (root->lchild()->value() > root->rchild()->value())
    			{
    				BaseNode<type> *rr = root->rchild();
    				root = root->lchild();
    				BaseNode<type> *tem = root->rchild();
    				if (!tem)
    					root->rchild(rr);
    				else {
    					BaseNode<type> *pr = root->rchild();
    					while (pr) {
    						if (pr->lchild() && pr->lchild()->value() > rr->value())
    							pr = pr->lchild();
    						else if (pr->rchild() && pr->rchild()->value() > rr->value())
    							pr = pr->rchild();
    						else
    							break;
    					}
    					if (!pr->lchild())
    						pr->lchild(rr);
    					else
    						pr->lchild(rr);
    				}
    			}
    			else {
    				BaseNode<type> *rr = root->lchild();
    				root = root->rchild();
    				BaseNode<type> *tem = root->lchild();
    				if (!tem)
    					root->lchild(rr);
    				else {
    					BaseNode<type> *pr = root->lchild();
    					while (pr) {
    						if (pr->lchild() && pr->lchild()->value() > rr->value())
    							pr = pr->lchild();
    						else if (pr->rchild() && pr->rchild()->value() > rr->value())
    							pr = pr->rchild();
    						else
    							break;
    					}
    					if (!pr->lchild())
    						pr->lchild(rr);
    					else
    						pr->rchild(rr);
    				}
    			}
    		}
    		else if (root->lchild())
    			root = root->lchild();
    		else
    			root = root->rchild();
    		--count;
    	}
    }
    
    template<class type>
    void treap<type>::travel(BaseNode<type> *pr) const
    {
    	if (pr) {
    		std::cout << pr->value() << ' ';
    		travel(pr->lchild());
    		travel(pr->rchild());
    	}
    }
    

      测试:

    #include <iostream>
    #include <vector>
    #include "Heap.cpp"
    
    int main()
    {
        std::vector<int> nums{1,5,3,2,4};
        treap<int> trees;
    
        for (auto v : nums)
            trees.insert(v);
    
        std::cout << "当前堆节点个数:" << trees.size() << std::endl;
    
        std::cout << "遍历堆树:";
        trees.show();
        std::cout << std::endl;
    
        while (!trees.empty()) {
            std::cout << "当前堆顶数据:" << trees.top() << std::endl;
            trees.remove();
        }
    
        return 0;
    }

      运行结果:

      在Windows上VS和CodeBlocks上都测试成功了,VS上是代码都在一个文件中测试的,codeblocks上不知道为什么必须用 #include "Heap.cpp" 而不能用 #include "Heap.h",否则会报错。。。

      CentOS7 gcc 8.1.0也测试成功了:

  • 相关阅读:
    课程笔记:——Javascript 中的预解释1
    我的博客园开通了~
    scheduling algorithm
    jQuery实现全选,全不选,反选
    jQuery实现表格选中行变色
    程序员永远的鸡血
    大家好,欢迎来到我的博客,我们一起成长,见证奇迹!
    存储过程和触发器优缺点分析
    ECStore去掉Index.php的方法
    C# 编码与解码
  • 原文地址:https://www.cnblogs.com/darkchii/p/8598466.html
Copyright © 2020-2023  润新知