国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[C/C++]詳解STL容器3--list的功能和模擬實(shí)現(xiàn)(迭代器失效問(wèn)題)

amc / 898人閱讀

摘要:本文介紹了的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),包括迭代器的實(shí)現(xiàn)。與為反向迭代器,對(duì)迭代器執(zhí)行操作,迭代器向前移動(dòng)。

本文介紹了list的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),包括list迭代器的實(shí)現(xiàn)。

目錄

一、list的介紹

二、list的常用接口的使用

1. list的構(gòu)造

2. list iterator的使用

3.list capacity的使用

4.list element access

5.list modifiers

6. list的迭代器失效

三、list與vector的對(duì)比

四、list的模擬實(shí)現(xiàn)


一、list的介紹

list 容器,又稱雙向鏈表容器,即該容器的底層是以雙向鏈表的形式實(shí)現(xiàn)的。這意味著,list 容器中的元素可以分散存儲(chǔ)在內(nèi)存空間里,而不是必須存儲(chǔ)在一整塊連續(xù)的內(nèi)存空間中。結(jié)構(gòu)如圖。

?list是可以在常數(shù)范圍內(nèi)在任意位置進(jìn)行插入和刪除的序列式容器,并且該容器可以前后雙向迭代

list與forward_list非常相似:最主要的不同在于forward_list是單鏈表,只能朝前迭代,已讓其更簡(jiǎn)單高效。

?與其他的序列式容器相比(array,vector,deque),list通常在任意位置進(jìn)行插入、移除元素的執(zhí)行效率更好。最大的缺陷是不支持任意位置的隨機(jī)訪問(wèn),必須從已知的位置(比如頭部或者尾部)迭代到該位置,在這段位置上迭代需要線性的時(shí)間;list還需要一些額外的空間,以保存每個(gè)節(jié)點(diǎn)的相關(guān)聯(lián)信息。

二、list的常用接口的使用

1. list的構(gòu)造

構(gòu)造函數(shù)( (constructor))接口說(shuō)明
list()構(gòu)造空的list
list (size_type n, const value_type& val = value_type())構(gòu)造的list中包含n個(gè)值為val的元素
list (const list& x)拷貝構(gòu)造函數(shù)
list (InputIterator first, InputIterator last)用[first, last)區(qū)間中的元素構(gòu)造list
#include #include int main (){    std::list a; // 構(gòu)造空的a    std::list b (4,1); // b中放4個(gè)值為100的元素    std::list c (b.begin(), b.end()); // 用b的[begin(), end())左閉右開(kāi)的區(qū)間構(gòu)造c    std::list d (c); // 用c拷貝構(gòu)造d    // 以數(shù)組為迭代器區(qū)間構(gòu)造e    int array[] = {16,2,77,29};    std::list e (array, array + sizeof(array) / sizeof(int) );    // 用迭代器方式打印e中的元素    for(std::list::iterator it = e.begin(); it != e.end(); it++)        std::cout << *it << " ";    std::cout<

2. list iterator的使用

函數(shù)聲明接口說(shuō)明
begin + end返回第一個(gè)元素的迭代器+返回最后一個(gè)元素下一個(gè)位置的迭代器
rbegin + rend返回第一個(gè)元素的reverse_iterator,即end位置,返回最后一個(gè)元素下一個(gè)位置的reverse_iterator,即begin位置

begin與end為正向迭代器,對(duì)迭代器執(zhí)行++操作,迭代器向后移動(dòng)。
rbegin(end)與rend(begin)為反向迭代器,對(duì)迭代器執(zhí)行++操作,迭代器向前移動(dòng)。

?

#include using namespace std;#include void print_list(const list& l){    // 注意這里調(diào)用的是list的 begin() const,返回list的const_iterator對(duì)象    for (list::const_iterator it = l.begin(); it != l.end(); ++it)    {        cout << *it << " ";        // *it = 10; 編譯不通過(guò)    }    cout << endl;}int main(){    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };    list l(array, array + sizeof(array) / sizeof(array[0]));    // 使用正向迭代器正向list中的元素    for (list::iterator it = l.begin(); it != l.end(); ++it)        cout << *it << " ";    cout << endl;    // 使用反向迭代器逆向打印list中的元素    for (list::reverse_iterator it = l.rbegin(); it != l.rend(); ++it)        cout << *it << " ";    cout << endl;    return 0;}

3.list capacity的使用

函數(shù)聲明接口說(shuō)明
empty檢測(cè)list是否為空,是返回true,否則返回false
size返回list中有效節(jié)點(diǎn)的個(gè)數(shù)

4.list element access

函數(shù)聲明接口說(shuō)明
front返回list的第一個(gè)節(jié)點(diǎn)中值的引用
back返回list的最后一個(gè)節(jié)點(diǎn)中值的引用

5.list modifiers

函數(shù)聲明接口說(shuō)明
push_front在list首元素前插入值為val的元素
pop_front刪除list中第一個(gè)元素
push_back在list尾部插入值為val的元素
pop_back刪除list中最后一個(gè)元素
insert在list position 位置中插入值為val的元素
erase刪除list position位置的元素
swap交換兩個(gè)list中的元素
clear清空l(shuí)ist中的有效元素

6. list的迭代器失效

此處可將迭代器暫時(shí)理解成類似于指針,迭代器失效即迭代器所指向的節(jié)點(diǎn)的無(wú)效,即該節(jié)點(diǎn)被刪除了。因?yàn)閘ist的底層結(jié)構(gòu)為帶頭結(jié)點(diǎn)的雙向循環(huán)鏈表,因此在list中進(jìn)行插入時(shí)是不會(huì)導(dǎo)致list的迭代器失效的,只有在刪除時(shí)才會(huì)失效,并且失效的只是指向被刪除節(jié)點(diǎn)的迭代器,其他迭代器不會(huì)受到影響。

三、list與vector的對(duì)比

vectorlist


結(jié)
構(gòu)
動(dòng)態(tài)順序表,一段連續(xù)空間帶頭結(jié)點(diǎn)的雙向循環(huán)鏈表

機(jī)

問(wèn)
支持隨機(jī)訪問(wèn),訪問(wèn)某個(gè)元素效率O(1)不支持隨機(jī)訪問(wèn),訪問(wèn)某個(gè)元素效率O(N)




任意位置插入和刪除效率低,需要搬移元素,時(shí)間復(fù)雜度為O(N),插入時(shí)有可能需要增容,增容:開(kāi)辟新空間,拷貝元素,釋放舊空間,導(dǎo)致效率更低




底層為連續(xù)空間,不容易造成內(nèi)存碎片,空間利用率高,緩存利用率高底層節(jié)點(diǎn)動(dòng)態(tài)開(kāi)辟,小節(jié)點(diǎn)容易造成內(nèi)存碎片,空間利用率低,緩存利用率低


原生態(tài)指針對(duì)原生態(tài)指針(節(jié)點(diǎn)指針)進(jìn)行封裝




在插入元素時(shí),要給所有的迭代器重新賦值,因?yàn)椴迦朐赜锌赡軙?huì)導(dǎo)致重新擴(kuò)容,致使原來(lái)迭代器失效,刪除時(shí),當(dāng)前迭代器需要重新賦值否則會(huì)失效插入元素不會(huì)導(dǎo)致迭代器失效,刪除元素時(shí),只會(huì)導(dǎo)致當(dāng)前迭代器失效,其他迭代器不受影響
使

場(chǎng)
需要高效存儲(chǔ),支持隨機(jī)訪問(wèn),不關(guān)心插入刪除效率大量插入和刪除操作,不關(guān)心隨機(jī)訪問(wèn)

四、list的模擬實(shí)現(xiàn)

?list的模擬實(shí)現(xiàn)十分有趣,這里需要注意,list本身和list的節(jié)點(diǎn)是不同的結(jié)構(gòu),所以需要分開(kāi)設(shè)計(jì)。成員都是只需淺拷貝,所以拷貝構(gòu)造,析構(gòu) ,重載 = 都可以使用默認(rèn)。

list?iterator也需要多帶帶設(shè)計(jì),因?yàn)樵羔樢呀?jīng)無(wú)法滿足迭代器需求,所以需要封裝,讓它像一個(gè)指針一樣完成訪問(wèn)操作。

通過(guò)template 區(qū)別T&,*T。

#include #include #include #include #include #include using namespace std;namespace Zht{  template     struct _list_node     //list本身和list的節(jié)點(diǎn)是不同的結(jié)構(gòu),所以需要分開(kāi)設(shè)計(jì),這里是list節(jié)點(diǎn)的結(jié)構(gòu)  {      T val;              //數(shù)據(jù)      _list_node* _next;       //下一個(gè)節(jié)點(diǎn)指針      _list_node* _prev;       //上一個(gè)            _list_node(const T& val = T())      //構(gòu)造節(jié)點(diǎn)        :val(val)                         //傳的參        ,_prev(nullptr)        ,_next(nullptr)      {                }  };  template   struct _list_iterator   {    typedef _list_node node;    typedef _list_iterator self;    node* _pnode;      //迭代器本質(zhì)上是指針    _list_iterator(node* pnode)     //構(gòu)造函數(shù)      :_pnode(pnode)    {    }    //這里,成員都是只需淺拷貝,所以拷貝構(gòu)造,析構(gòu) ,重載 = 都可以使用默認(rèn)       Ref operator*()       //重載*,通過(guò)Ref靈活的調(diào)整const和普通。    {      return _pnode->val;    }    bool operator!=(const self& s) const     {      return _pnode != s._pnode;    }    bool operator==(const self& s) const     {      return _pnode == s._pnode;    }    self& operator++()            //++就是指向下一個(gè)節(jié)點(diǎn)    {      _pnode = _pnode->_next;      return *this;    }    self operator++(int)          //C++規(guī)定后綴調(diào)用需要有一個(gè)int型參數(shù)作為區(qū)分前綴與后綴調(diào)用的區(qū)別    {      self tmp (*this);      ++*this;      return tmp;                 //*this++后++    }    self& operator--()    {      _pnode = _pnode->_prev;      return *this;    }    self operator--(int)    {      self tmp (*this);      --*this;      return tmp;    }    Ptr operator->()    {      return &(operator*());          }  };  template   class list  {      typedef _list_node node;  public:      typedef _list_iterator iterator;      typedef _list_iterator const_iterator;      list()      //構(gòu)造函數(shù),構(gòu)造哨兵位      {          _head = new node;           //開(kāi)一個(gè)節(jié)點(diǎn)          _head->_next = _head;       //初始化節(jié)點(diǎn)          _head->_prev = _head;      }      template       list(Iterator first, Iterator last)      {        _head = new node;        _head->_next = _head;        _head->_prev = _head;        while(first != last)        {          push_back(*first);          first++;        }      }      list(const list& It)      {        _head = new node;                   //構(gòu)造哨兵節(jié)點(diǎn)        _head->_next = _head;             _head->_prev = _head;        for(const auto& e : It)             //逐個(gè)尾插        {          push_back(e);        }      }      list& operator=(list It)      {        swap(_head, It._head);        return *this;      }      ~list()      {        clear();        delete _head;        _head = nullptr;      }      iterator begin()      {        return iterator(_head->_next);      }      const_iterator begin() const            //調(diào)用const的迭代器,返回一個(gè)用_head->next構(gòu)造的迭代器對(duì)象      {        return const_iterator(_head->_next);       }      iterator end()                                {        return iterator(_head);      }      const_iterator end() const       {        return const_iterator(_head);      }      void push_back(const T& x)        //只有哨兵位的也可以通用      {         /* node* newnode = new node(x);    //創(chuàng)建新節(jié)點(diǎn)          node* tail = _head->_prev;      //當(dāng)前的最后一個(gè)節(jié)點(diǎn)          tail->_next = newnode;          newnode->_next = _head;          newnode->_prev = tail;          _head->_prev = newnode;*/        insert(iterator(end()), x);     //前一個(gè)就是尾      }            void push_front(const T& x)      {        insert(iterator(begin),x);      }      void pop_back()      {        erase(iterator(--end()));      }      void pop_front()      {        erase(iterator(begin()));      }            iterator insert(iterator pos, const T& val)       //pos位置前插入      {        node* newnode = new node(val);        node* tail = pos._pnode;        newnode->_next = tail;        newnode->_prev = tail->_prev;        newnode->_prev->_next = newnode;              //還要讓前一個(gè)指向自己        pos._pnode->_prev = newnode;        return iterator(newnode);                     //需要返回迭代器;      }      iterator erase(iterator pos)    //刪除pos位置              {        assert(pos._pnode);        assert(pos != end());        node* tail = pos._pnode;        node* ret = tail->_next;        tail->_prev->_next = tail->_next;        tail->_next->_prev = tail->_prev;        delete tail;        return iterator(ret);       //返回下一個(gè)      }      bool empty()      {        return begin() == end();      }      size_t size()      {        size_t sz = 0;        iterator it = begin();        while(it != end())        {          sz++;          it++;        }        return sz;      }      void clear()      {        iterator it = begin();        while(it != end())        {          erase(it);          it++;        }      }        private:      node* _head;  };    void PrintList(const list& It)  {    list::const_iterator it = It.begin();    while(it != It.end())    {      cout << *it < lt;		lt.push_back(1);		lt.push_back(2);		lt.push_back(3);		lt.push_back(4);		list::iterator it = lt.begin();		while (it != lt.end())		{			*it += 1;			cout << *it << " ";			++it;		}		cout << endl;		for (auto e : lt)		{			cout << e << " ";		}		cout << endl;		PrintList(lt);  }}

?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/121133.html

相關(guān)文章

  • [C/C++]詳解STL1--string功能模擬實(shí)現(xiàn)(深淺拷貝問(wèn)題

    摘要:本文介紹了類的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),對(duì)模擬實(shí)現(xiàn)中涉及到的深淺拷貝問(wèn)題進(jìn)行了解析。在此之前,必須提到一個(gè)經(jīng)典問(wèn)題。為了解決淺拷貝問(wèn)題,所以中引入了深拷貝。但是實(shí)際使用中需要是第一個(gè)形參對(duì)象,才能正常使用。 本文介紹了string類的常用接口的使用,并對(duì)其進(jìn)行了模擬實(shí)現(xiàn),對(duì)模擬實(shí)...

    tianren124 評(píng)論0 收藏0
  • [C/C++ -STL]vector使用及迭代失效問(wèn)題詳解

    摘要:函數(shù)底層實(shí)際上是對(duì)指針的操作隸書(shū)向,范圍內(nèi)比較等于的第一個(gè)元素返回迭代器。指定位置元素的刪除操作使用查找所在位置的刪除位置的數(shù)據(jù),導(dǎo)致迭代器失效。因此刪除中任意位置上元素時(shí),就認(rèn)為該位置迭代器失效了。 ...

    VishKozus 評(píng)論0 收藏0
  • [C/C++ -STL]vector底層實(shí)現(xiàn)機(jī)制刨析

    摘要:并且由于的連續(xù)性,且循環(huán)中有迭代器的自加,所以在刪除一個(gè)元素后,迭代器需要減。隸書(shū)方案二與方案一在迭代器的處理上是類似的,不過(guò)對(duì)元素的訪問(wèn)采用了迭代器的方法。 一、...

    lowett 評(píng)論0 收藏0
  • [C/C++ -STL]list模擬實(shí)現(xiàn)list迭代底層刨析

    摘要:對(duì)類采用三個(gè)模板來(lái)實(shí)現(xiàn)迭代器。楷體類中和模板定義分別對(duì)應(yīng)迭代器中模板定義的楷體采用向上傳值的方式,傳入不同值來(lái)采用不同迭代器。首先是迭代器的,分為前置和后置。迭代器的和都是獲取迭代器所對(duì)應(yīng)的值。唯一的差別就是就是用到了迭代器。 ...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • C++】list詳解

    摘要:結(jié)果我們發(fā)現(xiàn),好像沒(méi)多大問(wèn)題,但是我們嘗試修改迭代器里面的內(nèi)容時(shí),卻發(fā)現(xiàn)能修改成功。注意為兩個(gè)迭代器之間的距離。報(bào)錯(cuò)這里的報(bào)錯(cuò)說(shuō)的是不在我們的迭代器當(dāng)中,這個(gè)是對(duì)我們迭代器類型的一個(gè)檢查。當(dāng)中為迭代器添加了如下聲明來(lái)解決這個(gè)問(wèn)題。 ...

    wanghui 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<