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<<"\trefCount = 1"<<endl;
    }
    
    SharedPtr(SharedPtr &other) : _ptr(other._ptr), _refCount(&(++*other._refCount))
    {
		cout<<"copy constructor : "<<*_ptr<<"\trefCount = "<<*_refCount<<endl;
    }
    
    ~SharedPtr()
    {
        if(_ptr && --*_refCount == 0) {
            cout<<*_ptr<<"\trefCount = 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<<"\t_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\n", H.erase(5));
	printf("%d\n", 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
posted @ 2020-04-27 11:38  我在地狱  阅读(301)  评论(3编辑  收藏  举报