zoukankan      html  css  js  c++  java
  • C++ code note

    unique_ptr

    #ifndef _UNIQUE_PTR_H
    #define __UNIQUE_H
    class Delete {   
    public:
        template<typename T>
        void operator()(T *p) const {
    		delete p;
        }
    };
    template<typename T,typename D = Delete >
    class unique_ptr {
    public:
        explicit unique_ptr(T *pp = nullptr ,const D &dd = D() ): 
    		un_ptr(pp), del(dd)
    	{
    	}
    		
        ~unique_ptr() 
    	{ 
            del(un_ptr); 
        } 
    	
        /* 不支持拷贝与赋值   */
        unique_ptr(const unique_ptr&) = delete ;
        unique_ptr& operator=(const unique_ptr& ) = delete ;
    
        /* 移动赋值与移动拷贝 */
        unique_ptr( unique_ptr&& right_value):
            un_ptr(right_value.un_ptr),del(std::move(right_value.del)) {
            right_value.un_ptr = nullptr ;
        }
    	
        unique_ptr& operator=( unique_ptr&& right_value ) noexcept {
            if(this != &right_value ){
                std::cout << "operator && right_value " << std::endl ;
                del(*this);
                un_ptr = right_value.un_ptr;
                del = std::move(right_value.del);
                right_value.un_ptr =  nullptr ;
            }
            return *this ;
        }
    	
        //u.release()   u 放弃对指针的控制权,返回指针,并将 u 置为空
        T* release(){ 
            T *tmp = un_ptr ;
            un_ptr = nullptr ;
            return  tmp;
        }
    	
        /*
        u.reset()   释放u指向的对象
        u.reset(q)  如果提供了内置指针q,就令u指向这个对象 
        u.reset(nullptr) 将 u 置为空
        */
        void reset(T* q = nullptr){
    		del(un_ptr);
    		un_ptr = q; 
        }
        void swap(unique_ptr &other ) noexcept {
            std::swap(un_ptr, other.un_ptr);
            std::swap(del, other.del) ;
        } 
        T* get() { return un_ptr; }
        D& get_deleter(){ return  del; }
        T& operator*()  { return *un_ptr; }
        T* operator->() { return  un_ptr; }
    private:
        T *un_ptr = nullptr ;
        D del ;
    };
    #endif
    

    shared_ptr

    https://www.cnblogs.com/howo/p/8468713.html
    
    //
    //  SharedPtr.hpp
    //  SharedPtr
    //
    //  Created by 顾浩 on 24/2/18.
    //  Copyright © 2018 顾浩. All rights reserved.
    //
    
    #ifndef SHARED_PTR_H
    #define SHARED_PTR_H
    
    #include <iostream>
    
    using namespace std;
    
    template<typename T>
    class SharedPtr {
    public:
        SharedPtr() : _ptr((T *)0), _refCount(0)
        {
        }
        
        SharedPtr(T *obj) : _ptr(obj), _refCount(new int(1))
        {
            cout<<"create object : "<<*_ptr<<"	refCount = 1"<<endl;
        }
        
        SharedPtr(SharedPtr &other) : _ptr(other._ptr), _refCount(&(++*other._refCount))
        {
    		cout<<"copy constructor : "<<*_ptr<<"	refCount = "<<*_refCount<<endl;
        }
        
        ~SharedPtr()
        {
            if(_ptr && --*_refCount == 0) {
                cout<<*_ptr<<"	refCount = 0. delete the _ptr:"<<*_ptr<<endl;
                delete _ptr;
                delete _refCount;
            }
        }
        
        SharedPtr &operator=(SharedPtr &other)
        {
            if(this==&other) return *this;
            ++*other._refCount;
            if(--*_refCount == 0) {
                cout<<"in function operator = . delete "<<*_ptr<<endl;
                delete _ptr;
                delete _refCount;
            }
            _ptr = other._ptr;
            _refCount = other._refCount;
            cout<<"in function operator = . "<<*_ptr<<"	_refCount = "<<*_refCount<<endl;
            return *this;
        }
        
        T *operator->()
        {
            if(_refCount == 0) return 0;
            return _ptr;
        }
        
        T &operator*()
        {
            if (_refCount == 0) return (T*)0;
            return *_ptr;
        }
        
    private:
        T *_ptr;
        int *_refCount;     //should be int*, rather than int
    };
    
    #endif /* SharedPtr_h */
    

    partion

    
    int par(T a[],int l,int r){
      int R = r;
      T x = a[R];
      while(l<r){
        while(l<r&&a[l]<=x)    ++l;
        while(l<r&&a[r]>=x)    --r;
        swap(a[l], a[r]);
      }
      swap(a[l], a[R]);
      return l;
    }
    T F(T A[], int l, int r, int k) {
      int pos = par(A, l, r);
      if(pos == k) return A[k];
      else if(pos < k) 
        return F(A, pos+1, r, k);
      else 
        return F(A, l, pos-1, k);
    }
    T Median( T A[], int N ){
      return F(A, 0, N-1, N/2);
    }
    

    hash_table

    template<class Value>
    struct __hashtable_node {
    	__hashtable_node *next;
    	Value val;
    };
    template<class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc>
    struct __hashtable_iterator {
    	typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> hashtable;
    	typedef __hashtable_node<Value> node;
    	
    	node *cur;
    	hashtable *ht;
    }
    
    
    
    template<class Value, class Key, class HashFcn, class ExtractKey, class EqualKey, class Alloc = alloc>
    class hashtable{
    public:
        typedef Key key_type;
        typedef Value value_type;
        typedef HashFcn hasher;
        typedef EqualKey key_equal;
        
        typedef size_t size_type;
        typedef ptrdiff_t difference_type;
        typedef value_type *pointer;
        typedef value_type &reference;
    private:
        hasher hash;
        key_equal equals;
        ExtractKey get_key;
        typedef __hashtable_node<Value> node;
        typedef simple_alloc<node, Alloc> node_alocator;
        vector<node*, Alloc> buckets;
        size_type num_elements;
    public:
        //hash_table源码中有重载的构造函数,这里我选了其中一种。
        hashtable(size_type n, const HashFcn& hf, const EqualKey& eql,
                  const ExtractKey& ext)
           :hash(hf),equals(eql),get_key(ext),num_elements(0)
        {
            initialize_buckets(n);
        }
        ~hashtable(){ clear(); }
        
    private:
        static const int __stl_num_prime_last = 28;
        static const unsigned long __stl_prime_list[__stl_num_primes] = 
        {
            53,         97,           193,         389,       769,
            1543,       3079,         6151,        12289,     24593,
            49157,      98317,        196613,      393241,    786433,
            1572869,    3145739,      6291469,     12582917,  25165843,
            50331653,   100663319,    201326611,   402653189, 805306457, 
            1610612741, 3221225473ul, 4294967291ul
        };
        void initialize_buckets(size_type n)
        {
            const size_type n_buckets = next_size(n);
            buckets.reserve(n_buckets);
            buckets.insert(buckets.end(), n_buckets, (node*)0);
            num_elements = 0;
        }
        size_type next_size(size_type n)const
        {
            return __stl_next_prime(n);
        }
        unsigned long __stl_next_prime(unsigned long n)
        {
            const unsigned long *first = __stl_prime_list;
            const unsigned long *last = __stl_prime_list + __stl_num_primes;
            const unsigned long *pos = lower_bound(first, last, n);
            return pos == last ? *(last-1) : *pos ;    
        }
    	
    	//STL中如何判断元素的落脚处
        size_type bkt_num(const value_type& obj, size_t n)const
        {
            return bkt_num_key(get_key(obj), n);
        }
        size_type bkt_num_key(const key_type& key, size_t n)
        {
            return hash(key) % n;
        }
    	
    	
        pair<iterator, bool> insert_unique(const value_type& obj)
        {
            resize(num_element + 1);    //插入元素前先判断需不需要重建vector
            return insert_unique_noresize(obj);
        }
    	
        template<class V, class K, clss HF, class Ex, class Eq, class A>
        void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_element_hint)
        {
            const size_type old_n = buckets.size();
            if(num_element_hint > old_n){
                const size_type n = next_size(num_element_hint);
                if(n > old_n){
                    vector<node *, A> tmp(n, (node*)0);
                    for(size_type bucket = 0; bucket < old_n; ++bucket){
                        node *first = buckets[bucket];
                        while(first){
                            size_type new_bucket = bkt_num(first->val, n);
                            buckets[bucket] = first->next;
                            first->next = tmp[new_bucket];
                            tmp[new_bucket] = first;
                            first = buckets[bucket];
                        }
                    }
                    buckets.swap(tmp);
                }
            }
        }
        template <class V, class K, class HF, class Ex, class Eq, class A>
        pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> 
        hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj)
        {
          const size_type n = bkt_num(obj);
          node* first = buckets[n];
        
          for (node* cur = first; cur; cur = cur->next) 
            if (equals(get_key(cur->val), get_key(obj)))
              return pair<iterator, bool>(iterator(cur, this), false);
        
          node* tmp = new_node(obj);
          tmp->next = first;
          buckets[n] = tmp;
          ++num_elements;
          return pair<iterator, bool>(iterator(tmp, this), true);
        }
    };
    

    my hashtable

    #include <bits/stdc++.h>
    using namespace std;
    
    template<class Value>
    struct hashtable_node {
    	Value val;
    	hashtable_node *next;
    	hashtable_node(Value val, hashtable_node *next):val(val), next(next){}
    };
    template<class Key>
    struct hashtable_iterator {
    	typedef hashtable_node<Key> node;
    	node *cur;
    };
    
    /***********************************************************************************************************/
    
    template<class Key, class Hash = std::hash<Key>, class KeyEqual = std::equal_to<Key>>
    struct hashtable{
        typedef hashtable_node<Key> node;
    	
        Hash hash;
        KeyEqual equals;
    	
        vector<node*> buckets;
        int num_elements;
    
        hashtable(int n = *prime_list){
    		num_elements = 0;
            int n_buckets = next_size(n);
            buckets.resize(n_buckets);
        }
        ~hashtable(){
        	for(auto cur: buckets) {
    			while(cur != NULL) {
    				node *tmp = cur->next;
    				delete cur;
    				cur = tmp;
    			}
    		}
    	}
    
    	node* find(const Key& obj) {
    		int n = hash(obj)%buckets.size();
    		node *cur = buckets[n];
    		while(cur) { 
    			if (equals(cur->val, obj)) 
    				return cur; 
    			cur = cur->next;
    		}
    		return cur;
    	}	
    	
    	pair<node*, bool> insert(const Key& obj, bool same = false) {
            resize(num_elements + 1);
            const int n = hash(obj)%buckets.size();
    		node* first = buckets[n], *cur = first;
    		while(cur) { 
    			if (equals(cur->val, obj)) {
    				if(same) {
    					node* tmp = new node(obj, cur->next);
    					*tmp = node{obj, cur->next};
    					cur->next = tmp;
    					++num_elements;
    					return {tmp, true};
    				}
    				return {cur, false};
    			}
    			cur = cur->next;
    		}
    		node* tmp = new node(obj, first);
    		buckets[n] = tmp;
    		++num_elements;
    		return {tmp, true};
        }
    	bool erase(const Key& obj, bool same = false) {
    		node* cur = find(obj);
    		if(cur == NULL) return false;		
    		while(cur && equals(cur->val, obj)) {
    			node *tmp = cur->next;
    			delete cur;
    			cur = tmp;
    			--num_elements;
    			if(!same) break ;
    		}		
    		return true;
    	}
    	
    private:
        static constexpr int _num_prime = 22;
        static constexpr int prime_list[_num_prime] = {
            53,         97,           193,         389,       769,
            1543,       3079,         6151,        12289,     24593,
            49157,      98317,        196613,      393241,    786433,
            1572869,    3145739,      6291469,     12582917,  25165843,
            50331653,   100663319 
        };
        int next_size(int n) {
            const int *last = prime_list+_num_prime;
            const int *pos = lower_bound(prime_list, last, n);
            return pos == last? *(last-1) : *pos;
        }
        void resize(int num) {
            int old_n = buckets.size();
            if(num > old_n){
                int n = next_size(num);
                if(n > old_n){
                    vector<node*> tmp(n, NULL);
                    for(int bucket = 0; bucket < old_n; ++bucket){
                        node *first = buckets[bucket];
                        while(first){
                            int new_bucket = hash(first->val)%n;
                            buckets[bucket] = first->next;
                            first->next = tmp[new_bucket];
                            tmp[new_bucket] = first;
                            first = buckets[bucket];
                        }
                    }
                    buckets.swap(tmp);
                }
            }
        }
    };
    
    
    int main() {
    	hashtable<int> H;
    	H.insert(3);
    	printf("%d
    ", H.erase(5));
    	printf("%d
    ", H.erase(3));
    	//H.insert(5, 0);
    	return 0;
    }
    

    B tree

    参考图: https://www.cnblogs.com/vianzhang/p/7922426.html
    
    B-tree
    B-tree中,一个节点的大小通常相当于一个完整的磁盘页。每次读一个节点相当于读一个磁盘页。
    最小度数t, 任意节点关键字数为[t-1, 2t-1]
    性质:
      每个节点有以下域:
    	n[x]: 当前x节点的关键字数
    	n[x]个关键字本身
    	leaf[x]:bool值,表示是否是叶节点
    	n[x]+1个指针, 指向其子节点
      叶节点深度相同
      每个非根节点至少包含t-1个关键字, 至多包含2t-1个关键字
    插入:
      自顶向下裂变, 沿途每遇到一个包含2t-1个关键字的节点, 将其中间节点往上提, 剩下2t-2个关键字裂变成2个节点。
    	(此操作保证了裂变的时候, 父节点的关键字数不是满的, 每次裂变完所有叶子节点依然在同一个深度。自底向上的话, 则不能保证。)
    删除:
      较复杂
      
    
    B+-tree
    与B-tree的不同:
      非叶节点只存储键值信息和指针
      所有叶节点之间有指针
      数据记录都存放在叶子节点
    优点:
      1. 一个块中可容纳更多的索引项,一是可以降低树的高度。二是一个内部节点可以定位更多的叶子节点
      2.叶子节点之间通过指针来连接,范围扫描将十分简单
    缺点:
      任意数据都需要搜索到叶节点才能找到
      
    https://www.cnblogs.com/hzy1991/p/8567334.html
    
  • 相关阅读:
    NIOS II常用函数整理
    C指针
    YCbCrYUV
    指针与引用的区别
    Pacman 命令详解
    DDR工作原理
    关于C/C++中的点操作符和箭头操作符
    千兆以太网芯片88E1111 RGMII模式的驱动
    关于建立时间和保持时间
    ECE 576 UDP Hardware
  • 原文地址:https://www.cnblogs.com/dirge/p/12785583.html
Copyright © 2011-2022 走看看