zoukankan      html  css  js  c++  java
  • 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

        */

        

       

        

        

        

    }







































  • 相关阅读:
    MapXtreme中鹰眼图与本地地图联动
    MapXtreme删除图层中某个对象
    winform textbox屏蔽中文输入法
    爬虫日记之美味汤的各种属性值的运用
    爬虫日记之robots协议
    爬虫日记之图片爬取和ip查询
    爬虫日记之关键字搜索引擎爬取
    爬虫之修改请求头
    爬虫第一步,re模块来铺路
    三个数据分析的模块
  • 原文地址:https://www.cnblogs.com/boydfd/p/4983169.html
Copyright © 2011-2022 走看看