STL list
2016-04-18 21:47
363 查看
/* * * Copyright (c) 2016 hujian. * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * file: hjstl_list.h * Author:hujian * Time:2016/4/18 */ #ifndef _HJSTL_LIST_H_ #define _HJSTL_LIST_H_ #include "hjstl_alloc.h" #include "hjstl_iterator.h" #include "hjstl_construct.h" #include "hjstl_uninitialized.h" #define _HJSTL_LIST_PUBLIC_ public #define _HJSTL_LIST_PRIVATE_ private #define _HJSTL_LIST_PROTECTED_ protected //this is the list node structure template<class Type> struct __hjstl_list_node{ typedef void* void_pointer;//this is the pointer type. void_pointer next;//the next pointer void_pointer prev;//the prev pointer Type data;//this is the node's data }; //so,this is the list iterator,and the list's iterator is //bidirectional type's iterator. template<class Type,class Reference,class Pointer> struct __hjstl_list_iterator{ //some typedefs typedef __hjstl_list_iterator<Type, Type&, Type*> iterator; typedef __hjstl_list_iterator<Type, const Type&, const Type*> const_iterator; typedef __hjstl_list_iterator<Type, Reference, Pointer> self; typedef hjstl_bidirectional_iterator_tag iterator_category; typedef Type value_type; typedef Pointer pointer; typedef Reference reference; typedef __hjstl_list_node<Type>* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; //this is the pointer to pointer to the node. //and the node will store the infomation of node. link_type hjstl_list_node; //the follow def is construct __hjstl_list_iterator(link_type x) :hjstl_list_node(x){} __hjstl_list_iterator(){} __hjstl_list_iterator(const iterator& x) :hjstl_list_node(x.hjstl_list_node){} //overload.... bool operator==(const self&x) const { return hjstl_list_node == x.hjstl_list_node; } bool operator!=(const self&x) const { return hjstl_list_node != x.hjstl_list_node; } //get the iterator's value. reference operator*()const { return (*hjstl_list_node).data; } pointer operator->()const{ return &(operator*()); } //increase the iterator,get the next iterator //++iterator self& operator++(){ hjstl_list_node = (link_type)((*hjstl_list_node).next); return *this; } //iterator++ self operator++(int){ self tmp = *this; ++(*this); return tmp; } //deincrease the iterator,and get the prev iterator //iterator-- self& operator--(){ hjstl_list_node = (link_type)((*hjstl_list_node).prev); return *this; } //iterator-- self operator--(int){ self tmp = *this; --(*this); return tmp; } };//end of list iterator template<class Type,class Ref,class Ptr> inline hjstl_bidirectional_iterator_tag iterator_category(const __hjstl_list_iterator<Type, Ref, Ptr>&){ return _HJSTL_bidirectional_iterator(); } template<class Type,class Ref,class Ptr> inline Type* hjstl_value_type(const __hjstl_list_iterator<Type, Ref, Ptr>&){ return 0; } template<class Type,class Ref,class Ptr> inline ptrdiff_t* distance_type(const __hjstl_list_iterator<Type, Ref, Ptr>&){ return 0; } //this is the list class //the default allocate is the memory pool. template<class Type,class Alloc=HJSTL_Alloc::Alloc_second> class _HJSTL_list{ //_HJSTL_LIST_PROTECTED_: __HJSTL_PUBLIC_: typedef void* void_pointer; typedef __hjstl_list_node<Type> list_node; //the alloc..... typedef _HJSTL_simple_alloc<list_node, Alloc> hjstl_list_node_allocator; __HJSTL_PUBLIC_: typedef Type value_type; typedef value_type* pointer; typedef const value_type* const_pointer; typedef value_type& reference; typedef const value_type& const_reference; typedef list_node* link_type; typedef size_t size_type; typedef ptrdiff_t difference_type; //so,this node will manage all list. //because the list is double list,so,just one pointer needed. link_type this_node; ////test void* test_ptr; //the iterator of this list typedef __hjstl_list_iterator<Type, Type&, Type*> iterator; typedef __hjstl_list_iterator<Type, const Type&, const Type*> const_iterator; //_HJSTL_LIST_PROTECTED_: _HJSTL_LIST_PUBLIC_: //alloc an node,and return the node link_type get_node(){ return hjstl_list_node_allocator::allocate(); } //free an node void put_node(link_type p){ hjstl_list_node_allocator::deallocate(p); } //create an new node,and with value link_type create_node(const Type& v){ link_type p = get_node(); try{ construct(&p->data, v); } catch (...){ //if error,free the node put_node(p); } return p; } //destroy an node void destroy_node(link_type p){ destroy(&p->data); put_node(p); } //the initialze function,just set up the double circle list void _empty_initialze(){ //circle and double director this_node = get_node(); this_node->next = this_node; this_node->prev = this_node; } //create n node,and initialze with value void _fill_initialze(size_type n,const Type& value){ //set up the list _empty_initialze(); try{ //insert node,and init the value insert(begin(), n, value); } catch (...){ clear(); put_node(this_node); } } //range initialze void range_initialze(const Type* first, const Type* last){ //set up _empty_initialze(); try{ insert(begin(), first, last); } catch (...){ clear(); destroy_node(this_node); } } //set up the list _HJSTL_list() { _empty_initialze(); } _HJSTL_list(size_type n, const Type& value){ _fill_initialze(n, value); } _HJSTL_list(int n, const Type&value){ _fill_initialze(n, value); } _HJSTL_list(long n, const Type& value){ _fill_initialze(n, value); } _HJSTL_list(size_type n){ _fill_initialze(n, Type()); } _HJSTL_list(const Type* first, const Type* last){range_initialze(first, last);} _HJSTL_list(const _HJSTL_list<Type, Alloc>& x){range_initialze(x.begin(), x.end());} //the list's transfer.very magic function but so easy to write //move the [first,last) to before position void transfer(iterator position, iterator first, iterator last) { if (position != last) { (*(link_type((*last.hjstl_list_node).prev))).next = position.hjstl_list_node; (*(link_type((*first.hjstl_list_node).prev))).next = last.hjstl_list_node; (*(link_type((*position.hjstl_list_node).prev))).next = first.hjstl_list_node; link_type tmp = link_type((*position.hjstl_list_node).prev); (*position.hjstl_list_node).prev = (*last.hjstl_list_node).prev; (*last.hjstl_list_node).prev = (*first.hjstl_list_node).prev; (*first.hjstl_list_node).prev = tmp; } } //splice //different list void splice(iterator position, _HJSTL_list& x) { if (!x.empty()){ transfer(position, x.begin(), x.end()); } } //same list void splice(iterator position, _HJSTL_list&, iterator i) { iterator j = i; ++j; if (position == i || position == j){ return; } transfer(position, i, j); } void splice(iterator position, _HJSTL_list&, iterator first, iterator last) { if (first != last){ transfer(position, first, last); } } //remove the value. void remove(const Type& value) { iterator first = begin(); iterator last = end(); while (first != last){ iterator next = first; ++next;//move to next,no influence the list operator<traversal> if (*first == value) erase(first); first = next; } } //unique //this is about algorithm void unique() { iterator first = begin(); iterator last = end(); if (first == last) return; iterator next = first; while (++next != last){ if (*first == *next){ erase(next); } else{ first = next; } next = first; } } //merge,you need to ensure the two list has sorted void merge(_HJSTL_list& x) { iterator first1 = begin(); iterator last1 = end(); iterator first2 = x.begin(); iterator last2 = x.end(); while (first1 != last1&&first2 != last2) { if (*first2 < *first1){ iterator next = first2; //only first2 will be moved to---> ...[first2][first1]... transfer(first1, first2, ++next); first2 = next; } else{ ++first1; } if (first2 != last2){ //more data transfer(last1, first2, last2); } } } //reserve the list //this is magic... void reserve() { //judge if this is a empty list,or just one elements if (this_node->next == this_node || link_type(this_node->next)->next == this_node){ return; } iterator first = begin(); ++first; while (first != end()){ iterator old = first; ++first; //only one elements will be moved transfer(begin(), old, first); } } //sort this list //quick sort void sort() { //judge wether this list only one element or empty if (this_node->next == this_node || ((link_type)(this_node->next))->next == this_node){ return; } _HJSTL_list<Type, Alloc> carry; _HJSTL_list<Type, Alloc> counter[64]; int fill = 0; while (!empty()) { carry.splice(carry.begin(), *this, begin()); int i; while (i < fill&&!counter[i].empty()){ counter[i].merge(carry); carry.swap(counter[i++]); } carry.swap(counter[i]); if (i == fill) ++fill; } for (int i = 0; i < fill; i++){ counter[i].merge(counter[i - 1]); } swap(counter[fill - 1]); } //get the begin iterator iterator begin(){ //cause the this_node is the flag of this list //so,the this_node is empty forever return (link_type)((*this_node).next); } //get the end iterator iterator end(){ //and this is empty. return ((this_node)); } //is empty? bool empty(){ return this_node->next == this_node; } //the size of this list size_type size(){ size_type result = 0; hjstl_distance(begin(), end(), result); return result; } //the max size size_type max_size() const{ return size_type(-1); } //get the front's value reference front(){ return *begin(); } //get the back reference back(){ return *(--end()); } //swap void swap( _HJSTL_list<Type, Alloc>&x ){ swap(this_node, x); } //insert a node,before position... iterator insert(iterator position, const Type& v) { /* before insert ....[]-[]-[position]-[]-[]-[]..... running ....[]-[]-[position]-[]-[]-[]...... -[tmp]- after insert ....[]-[]-[tmp]-[position]-[]-[]-[]...... */ //this is the node will insert link_type tmp = create_node(v); tmp->next = position.hjstl_list_node; tmp->prev = position.hjstl_list_node->prev; ((link_type)(position.hjstl_list_node->prev))->next = tmp; position.hjstl_list_node->prev = tmp; return tmp; } //insert null before position iterator insert(iterator position){ return insert(position, Type()); } ///push.... void push_front(const Type& v){ insert(begin(), v); } void push_back(const Type& v){ insert(end(), v); } //pop... void pop_front(){erase(begin());} void pop_back(){ iterator tmp = end(); erase(--tmp); } template<class InputIterator> void insert(iterator position, InputIterator first, InputIterator last) { for (; first != last; ++first){ insert(position, *first); } } void insert(iterator position, const Type* first, const Type* last) { for (; first != last; ++first){ insert(position, *first); } } void insert(iterator position, const_iterator first, const_iterator last) { for (; first != last; ++first){ insert(position, *first); } } void insert(iterator pos, size_type n, const Type& x) { for (; n > 0; --n){ insert(pos, x); } } void insert(iterator pos, int n, const Type& x) { insert(pos, (size_type)n, x); } void insert(iterator pos, long n, const Type& x) { insert(pos, (size_type)n, x); } //erase iterator erase(iterator position) { /* before erase ...[]-[position]-[]... running ...[]-...-[]... after ...[]-[]... */ link_type next_node = link_type(position.hjstl_list_node->next); link_type prev_node = link_type(position.hjstl_list_node->prev); prev_node->next = next_node; next_node->prev = prev_node; //destroy this node destroy_node(position.hjstl_list_node); return iterator(position.hjstl_list_node); } //another erase function //[first,last) iterator erase(iterator first, iterator last) { //erase range...iterators while (first != last){ erase(first++); } return last; } //resize void resize(size_type new_szie, const Type& v) { iterator it = begin(); size_type len = 0; for (; it != end() && len < new_szie; i++, len++); //more space left if (len == new_szie){ erase(it, end()); } else{//no so many nodes. insert(end(), new_szie - len, v); } } //resize and no initialze void resize(size_type new_size){ resize(new_size, Type()); } //clear the list void clear() { //this_node is the flag,and it's null link_type curr = (link_type)this_node->next; while (curr != this_node){ link_type tmp = curr; curr = (link_type)curr->next; destroy_node(tmp); } //reset the list this_node->next = this_node; this_node->prev = this_node; } //operator = _HJSTL_list<Type, Alloc>& operator=(const _HJSTL_list<Type, Alloc>& x) { //if same obj,just return if (this != &x){ iterator first1 = begin(); iterator last1 = end(); const_iterator first2 = x.begin(); const_iterator last2 = x.end(); while (first1 != last1&&first2 != last2){ *first1++ = *first2++; } //check if (first2 == last2){ //more.... erase(first1, last1); } else{//no so many nodes,so insert some empty nodes insert(last1, first2, last2); } } return *this; } //deconstruct ~_HJSTL_list() { clear(); put_node(this_node); } };//end of hjstl list #endif //end of _HJSTL_LIST_H_
相关文章推荐
- mysql存储过程
- 使用苹果自带的Reachability监听网络状态
- 向量一些概念
- Java并发编程(二)线程任务的中断(interrupt)
- Python开发工具介绍(PyCharm)
- codevs1506传话(kosaraju算法)
- Tomcat学习笔记 虚拟主机
- 小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)
- python系列之 - select
- Android性能优化-StrictMode(严苛模式)
- 设计模式
- JavaScript基础知识逐步理解。
- NYOJ 734
- Windows 网络问题
- Apple Store连网后内容空白页的解决办法
- 学习REST
- 2015高教杯全国大学生数学建模竞赛论文
- LeetCode Rotate Array
- 什么是软件质量?试叙述它与软件可靠性的关系。
- 来一道水题 KMP算法---HDU2087