stl源码剖析 详细学习笔记priority_queue slist

//

//  priority_queue.cpp

//  笔记

//

//  Created by fam on 15/3/16.

//

//


//---------------------------15/03/16----------------------------





//priority_queue

{

    /*

        priority_queue概述:

        同正常队列一样,队尾进,队首出,不过不是先进后出,

        有权值的概念,所以会自动排序(并不是全部排序,只要保证队

        首值最大即可,权值最高的最先出队列,这里用的是堆来保证队首

        的值

    */

    

    template<class T, class Sequence = vector<T>,

            class Compare = less<typename Sequence::value_type> >

    class priority_queue

    {

    public:

        typedef typename Sequence::value_type value_type;

        typedef typename Sequence::size_type size_type;

        typedef typename Sequence::reference reference;

        typedef typename Sequence::const_reference const_reference;

        

    protected:

        Sequence c;

        Compare comp;

        

    public:

        priority_queue() : c(){};

        //explict 可以有效防止隐式转化

        explicit priority_queue(const Compare& x) : c(), comp(x){}

        

        //下面都是直接调用heap算法来直接实现堆的操作

        template<class InputIterator>

        priority_queue(InputIterator first, InputIterator last, const Compare& x)

          :c(first,last), comp(x){ make_heap(c.begin(), c.end(), comp);}

        

        template< class InputIterator>

        priority_queue(InputIterator first, InputIterator last)

          : c(first, last) {make_heap(c.begin(), c.end(), comp);}

        

        bool empty() const {return c.empty();}

        size_type size() const {return c.size();}

        const_reference top() const {return c.front();}

        

        void push(const value_type& x)

        {

            __STL_TRY

            {

                

                c.push_back(x);

                

                push_heap(c.begin(), c.end(), comp);

            }

            

            __STL_UNWIND(c.clear());

        }

        

        void pop()

        {

            __STL_TRY

            {

                pop_heap(c.begin(), c.end(), comp);

                c.pop_back();

            }

            

            __STL_UNWIND(c.clear());

        }

        

        /*  

            总结:

            queue 不提供迭代器。

            不同queue,底层实现是用vector实现的(queue底层是deque实现的)

            原因:queue每次进队列都在队尾,出队列都在队首,频繁地对头尾进行操作,

            dequevector性能好很多

            

            priority_queue虽然也是队尾进,队首出,但是不可避免的是每次都要调整位置,

            所以采用堆加vector是很好的选择(deque的随机访问是要比vector慢的),采用

            堆每次插入,取出,都只用log(n)的时间,所以很好.

        */


        

    };

    

}




//slist

{

    /*

        slist概述:

        list是双向链表(double linked list),slist是单向链表

        slist的迭代器属于单向的ForwardIterator,所以功能被限制了很多

        但是耗用的空间小,操作更快.(我们大部分人最先接触的链表数据结构就是单向链表)

        slist不提供push_back(),

    */

    

    //__slist_node

    struct __slist_node_base

    {

        __slist_node_base* next;

    };


    template <class T>

    struct __slist_node : public __slist_node_base

    {

        T data;

    };

    

    //添加一个节点(new_node)prev_node之后

    inline __slist_node_base* __slist_make_link(

                                __slist_node_base* prev_node,

                                __slist_node_base* new_node)

    {

        new_node->next = prev_node->next;

        prev_node->next = new_node;

        return new_node;

    }

    

    //通过循环判断node节点之后(包括node节点)一共有多少节点

    inline size_t __slist_size(__slist_node_base* node)

    {

        

        size_t result = 0;

        for(; node != 0; node = node->next)

            ++result;

        return result;

    }

    

    

    

    //__slist_iterator

    struct __slist_iterator_base

    {

        

        typedef size_t size_type;

        typedef ptrdiff_t difference_type;

        typedef forward_iterator_tag iterator_category;

        

        //这里用基类创建一个节点

        __slist_node_base* node;

        

        __slist_iterator_base(__slist_node_base* x) :node(x){}

        

        //相当于++操作

        void incr() { node = node->next; }

        

        //迭代器是否相等取决于他们的节点是否相等

        bool operator==(const __slist_iterator_base& x) const

        {

            return node == x.node;

        }

        

        bool operator!=(const __slist_iterator_base& x) const{

            return node != x.node;

        }

    };

    

    //T: class Ref class& Ptr  class*

    template<class T, class Ref, class Ptr>

    struct __slist_iterator : public __slist_iterator_base

    {

      

        typedef __slist_iterator<T, T&, T*>     iterator;

        typedef __slist_iterator<T, const T&, const T*>     const_iterator;

        typedef __slist_iterator<T, Ref, Ptr>   self;

        

        typedef T   value_type;

        typedef Ptr pointer;

        typedef Ref reference;

        

        //节点类型

        typedef __slist_node<T> list_node;

        

        __slist_iterator(list_node* x) : __slist_iterator_base(x) {}

        

        

        __slist_iterator() : __slist_iterator_base(0){}

        

        __slist_iterator(const iterator& x) : __slist_iterator_base(x.node) {}

        

        //node__slist_node_base类型 需要强制转化

        reference operator*() const {return ((list_node*) node)->data;}

        

        pointer operator->() const {return &(operator*());}

        

        self& operator++()

        {

            incr();

            return *this;

        }

        

        self operator++(int)

        {

            self temp = *this;

            incr();

            return temp;

        }

        //并没有operator--操作

        

        

    };

    

    

    //class slist

    

    template< class T, class Alloc = allic>

    class slist

    {

    public:

        typedef T value_type;

        typedef value_type* pointer;

        typedef const value_type* const_pointer;

        typedef value_type& reference;

        typedef const value_type& const_reference;

        typedef size_t size_type;

        typedef ptrdiff_t difference_type;

        

        typedef __slist_iterator<T, T&, T*> iterator;

        typedef __slist_iterator<T, const T&, const T*> const_iterator;

        

    private:

        typedef __slist_node<T> list_node;

        typedef __slist_node_base list_node_base;

        typedef __slist_iterator_base iterator_base;

        typedef simple_alloc<list_node, Alloc> list_node_allocator;

        

        //申请内存并调用构造函数

        static list_node* create_node(const value_type& x)

        {

            list_node* node = list_node_allocator::allocate();

            __STL_TRY

            {

                construct(&node->data, x);

                node->next=0;

            }

            __STL_UNWIND(list_node_allocator::deallocate(node));

            return node;

        }

        

        static void destroy_node(list_node* node)

        {

            destroy(&node->data);

            list_node_allocator::deallocate(node);

        }

        

    private:

        list_node_base head;

        

    public:

        slist() { head.next = 0; }

        

        //clear()是循环删除所有节点

        ~slist() {clear();}

        

        iterator begin() {return iterator((list_node*)head.next);}

        

        //强制转化一个0iterator类型表示end

        //最开始的时候,head.next等于0 表示末尾;

        iterator end() {return iterator(0);}

        size_type size() const {return __slist_size(head.next);}

        bool empty() const {return head.next == 0;}

        

        void swap(slist& L)

        {

            list_node_base* tmp =head.next;

            head.next = L.head.next;

            L.head.next = tmp;

        }

        

    public:

        reference front() {return ((list_node*) head.next)->data;}

        

        void push_front(const value_type& x)

        {

            __slist_make_link(&head, create_node(x));

        }

        

        void pop_front()

        {

            list_node* node = (list_node*) head.next;

            head.next = node->next;

            destroy_node(node);

        }

        

    };

    

    /*

        总结:

        deque一样,我还是不知道为什么在迭代器中会有selfiterator两个typedef

        为什么要特地弄出两个基类? 这样的好处貌似是一个链表可以存放不同的数据类型,但是

        并没有用啊。在使用slist<T>来声明定义变量时就确定了类型了。

   别的没什么特别的技巧,就是一个很普通的list

    */

    

   

    

    

    

}







































posted @ 2015-03-16 21:37  boydfd  阅读(301)  评论(0编辑  收藏  举报