• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-91  評論-137  文章-0  trackbacks-0
            在STL中l(wèi)ist是以雙向鏈表的方式來存儲的,應(yīng)此使用給定的下標(biāo)值來找到對應(yīng)的節(jié)點所需的時間復(fù)雜度為O(n),相比vector直接使用原生指針會慢一些。

            因為是雙向鏈表的關(guān)系,那么必然有一種結(jié)構(gòu)來表示鏈表中的節(jié)點。
                    template <typename T>
                    struct __list_node
                    {
                        __list_node<T>* prev;
                        __list_node<T>* next;
                        T data;

                        __list_node() : prev(NULL), next(NULL)
                        {
                        }

                        __list_node(const T& x) : prev(NULL), next(NULL), data(x)
                        {
                        }
                    };

            然后我們定義出其iterator和const_iterator的結(jié)構(gòu)
                    template <typename T>
                    struct __list_iterator
                    {
                        typedef __list_iterator<T> iterator;
                        typedef T                  value_type;
                        typedef ptrdiff_t          difference_type;
                        typedef T*                 pointer;
                        typedef T&                 reference;
                        typedef const T*           const_pointer;
                        typedef const T&           const_reference;
                        typedef __list_node<T>*    link_type;
                        typedef void*              void_pointer;

                        link_type node;

                        __list_iterator(link_type x) : node(x)
                        {
                        }

                        __list_iterator(const __list_const_iterator<T>& x) : node(x.node)
                        {
                        }

                        __list_iterator() : node(NULL)
                        {
                        }

                        inline iterator& operator++()
                        {
                            node = ((link_type)node)->next;
                            return *this;
                        }

                        inline iterator operator++(int)
                        {
                            iterator tmp = *this;
                            ++*this;
                            return tmp;
                        }

                        inline iterator& operator--()
                        {
                            node = ((link_type)node)->prev;
                            return *this;
                        }

                        inline iterator operator--(int)
                        {
                            iterator tmp = *this;
                            --*this;
                            return tmp;
                        }

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

                        inline bool operator==(const iterator& x)const
                        {
                            return node == x.node;
                        }

                        inline bool operator!=(const iterator& x)const
                        {
                            return node != x.node;
                        }
                    };
            由于const_iterator與iterator的結(jié)構(gòu)類似,這里不再貼出。其中重載了++與--運算符,實際上就是節(jié)點的前后移動。

            然后看一下list的定義
                    template <typename T>
                    class list
                    {
                    }

            讓我們來看看list中的別名
                    public:
                        typedef T                        value_type;
                        typedef T*                       pointer;
                        typedef __list_iterator<T>       iterator;
                        typedef __list_const_iterator<T> const_iterator;
                        typedef T&                       reference;
                        typedef const T&                 const_reference;
                        typedef size_t                   size_type;
                        typedef ptrdiff_t                difference_type;
                        typedef reverse_iterator<const_iterator, value_type, size_type, difference_type> const_reverse_iterator;
                        typedef reverse_iterator<iterator, value_type, size_type, difference_type> reverse_iterator;

            下面是其內(nèi)部的成員變量
                    protected:
                        typedef __list_node<T>*           link_type;
                        typedef list<T>                   self;
                        typedef allocator<__list_node<T> > Node_Alloc;

                        link_type node;
                        size_type length;
            在STL中從begin到end總是以一個前閉后開的形式來表示的,應(yīng)此我們給出一個node節(jié)點來表示end所指位置,而node節(jié)點的前驅(qū)則是這個list的起始節(jié)點,而length則存儲了這個list的元素數(shù)量。

            下面來看看list中最基本的構(gòu)造函數(shù)和析構(gòu)函數(shù)
                        list() : length(0)
                        {
                            node = Node_Alloc::allocate();
                            node->next = node;
                            node->prev = node;
                        }

                        ~list()
                        {
                            clear();
                            Node_Alloc::deallocate(node);
                        }
            在list對象構(gòu)造之初,首先構(gòu)造出node節(jié)點,使其的前驅(qū)和后繼都指向其本身,應(yīng)此通過begin和end拿出的迭代器為同一個。在list對象析構(gòu)時,首先將這個list清空,然后將構(gòu)造出的node節(jié)點釋放掉。

            然后是其begin和end方法,用來獲取第一個元素和最后一個元素的后一個元素的迭代器
                        inline iterator begin()
                        {
                            return node->next;
                        }

                        inline const_iterator begin()const
                        {
                            return node->next;
                        }

                        inline iterator end()
                        {
                            return node;
                        }

                        inline const_iterator end()const
                        {
                            return node;
                        }

            front和back分別被用來獲取第一個元素和最后一個元素
                        inline reference front()
                        {
                            return *begin();
                        }

                        inline const_reference front()const
                        {
                            return *begin();
                        }

                        inline reference back()
                        {
                            return *end();
                        }

                        inline const_reference back()const
                        {
                            return *end();
                        }

            empty、size分別被用來判別容器是否為空、獲取容器內(nèi)元素的個數(shù)
                        inline bool empty()const
                        {
                            return length == 0;
                        }

                        inline size_type size()const
                        {
                            return length;
                        }

            list與vector不同的是list是雙向的,應(yīng)此它允許從頭尾兩個方向來插入和刪除元素
                        inline void push_front(const T& x)
                        {
                            insert(begin(), x);
                        }

                        inline void push_back(const T& x)
                        {
                            insert(end(), x);
                        }

                        inline void pop_front()
                        {
                            erase(begin());
                        }

                        inline void pop_back()
                        {
                            erase(--end());
                        }

            然后我們來看一下push的本質(zhì),insert函數(shù)
                        iterator insert(const iterator& position, const T& x)
                        {
                            if(!inRange(position)) throw "out of range";
                            link_type tmp = Node_Alloc::allocate();
                            construct(tmp, x);
                            tmp->prev = position.node->prev;
                            tmp->next = position.node;
                            position.node->prev->next = tmp;
                            position.node->prev = tmp;
                            ++length;
                            return tmp;
                        }
            這里首先會檢查這個迭代器是否屬于這個list,然后構(gòu)造出一個新節(jié)點,并把它插入到這個迭代器的前面,最后將節(jié)點數(shù)+1。

            然后是其刪除節(jié)點函數(shù)erase
                        void erase(const iterator& position)
                        {
                            if(!inRange(position)) throw "out of range";
                            position.node->prev->next = position.node->next;
                            position.node->next->prev = position.node->prev;
                            destruct(&position.node->data, has_destruct(position.node->data));
                            Node_Alloc::deallocate(position.node);
                            --length;
                        }
            這里同樣會檢查這個迭代器是否屬于這個list,然后將這個節(jié)點移除,最后析構(gòu)并釋放內(nèi)存空間。

            最后讓我們來看一下list中重載的運算符
                        self& operator=(const self& x)
                        {
                            if(this == &x) return *this;

                            iterator first1 = begin();
                            iterator last1 = end();
                            const_iterator first2 = x.begin();
                            const_iterator last2 = x.end();
                            while (first1 != last1 && first2 != last2) *first1++ = *first2++;
                            if (first2 == last2) erase(first1, last1);
                            else insert(last1, first2, last2);
                            return *this;
                        }

                        reference operator[](size_type n)
                        {
                            if(n < 0 || n >= length) throw "out of range";
                            link_type current = NULL;
                            if(n < length / 2)
                            {
                                current = node->next;
                                for(size_type i = 0; i < n; i++, current = current->next);
                            }
                            else
                            {
                                n = length - n - 1;
                                current = node->prev;
                                for(size_type i = 0; i < n; i++, current = current->prev);
                            }
                            return current->data;
                        }

                        inline value_type at(size_type n)
                        {
                            return operator[](n);
                        }
            因為其內(nèi)部使用的是雙向鏈表,應(yīng)此通過指定下標(biāo)來獲取這個元素是可分別從兩頭進行移動指針。

            至此,list的講解已完成,完整代碼請到http://qlanguage.codeplex.com下載
            posted on 2012-08-09 21:17 lwch 閱讀(1830) 評論(0)  編輯 收藏 引用 所屬分類: STL
            好久久免费视频高清| 久久久久久久综合狠狠综合| 亚洲日本久久久午夜精品| 久久99精品国产麻豆蜜芽| 成人精品一区二区久久久| 久久精品国产精品国产精品污| 激情伊人五月天久久综合| 丰满少妇高潮惨叫久久久| 久久精品夜夜夜夜夜久久| 久久99精品久久久久婷婷| 国内精品九九久久久精品| 蜜桃麻豆www久久| 国产精品久久久久久久久久免费| 99久久精品无码一区二区毛片| 99久久精品九九亚洲精品| 久久久久亚洲AV成人网| 亚洲七七久久精品中文国产 | 久久婷婷五月综合色高清| 久久久无码一区二区三区| 久久久国产精品福利免费| 国产巨作麻豆欧美亚洲综合久久 | 国产69精品久久久久APP下载| 久久久国产打桩机| 国产精品久久久久国产A级| 国产无套内射久久久国产| 亚洲AⅤ优女AV综合久久久| 久久人人添人人爽添人人片牛牛| 久久国产亚洲精品无码| 久久最新免费视频| 亚洲午夜久久久久久久久电影网| 97精品国产91久久久久久| 久久人人爽人人精品视频| 无码国产69精品久久久久网站| 久久久青草久久久青草| 亚洲国产精品成人AV无码久久综合影院 | 午夜不卡久久精品无码免费| 91精品国产91久久久久久青草| 亚洲欧美成人久久综合中文网| 国内精品久久国产大陆| 人妻无码αv中文字幕久久琪琪布| 久久精品人人做人人爽电影|