鍊錶是一種線性表,但不會按照線性的順序儲存。鍊錶每次插入和刪除乙個元素,只配置或者釋放乙個元素空間,對於任何位置的元素的插入或者刪除,list永遠是常量時間複雜度。
template struct listnode
;
節點物件包含兩個節點物件指標,分別指向前乙個節點和後乙個節點,還有乙個節點物件存放的資料。用節點儲存乙個資料物件會額外的多占用兩個指標空間。
因為vector是記憶體中連續的空間,可以用普通指標當做vector的迭代器,list在記憶體空間中並不是連續的,都是用當前節點尋找前後節點,因此不能以普通指標當做迭代器。list的迭代器必須有能力指向list的節點,並且有能力進行正確的遞增、遞減、取值和成員訪問等操作。
template struct listiterator
listiterator(linktype x):node(x){}
listiterator(const listiterator& x):node(x.node){}
bool operator==(const self& x)const
bool operator!=(const self& x)const
reference operator*()const
point operator->()const
//prefixform ++
self& operator++()
//postfixform ++
self operator++(int)
//prefixform --
self& operator--()
//postfixform --
self operator--(int)
public:
linktype node;
};
迭代器失效:list的插入和結合操作都不會造成原有list的迭代器失效,vector不具備這種特性,因為vector的操作可能造成空間的重新分配,導致原有的迭代器全部失效。對於list被刪除的那個元素,也只是當前刪除物件的迭代器失效,其他迭代器不受影響。
list只需要乙個指標就可以完整表現整個鍊錶。
class list
;
list()
list(size_type n){}
list(size_type n, ty value){}
list(iterator first,iterator last){}
~list()
iterator begin()
iterator end()
bool empty()const
size_type size()const
reference front()
reference back()
void push_front(const ty& x)
void push_back(const ty& x)
iterator insert(iterator position, const ty& x)
void pop_front()
void pop_back()
iterator erase(iterator position)
void clear()
node->_m_next = node;
node->_m_prev = node;
}
void remove(const ty&x)
}
void unique()
else
next = first;//修正區段範圍}}
void reverse()
}
分別進行int資料物件和class物件進行鍊錶介面測試驗證,並且驗證物件析構時,是否有記憶體洩露問題
#include #include #include#include"stl_list.h"
class test_class_t_obj
std::cout << "construct this obj address is:" << this << "\n";
} ~test_class_t_obj()
std::cout << "deconstruct this obj address is:" << this << "\n";
}private:
int m_malloclen;
void* m_ptr;
};int main()
std::cout << std::endl;
intlist.reverse();
for (auto iter = intlist.begin(); iter != intlist.end(); ++iter)
std::cout << std::endl;
intlist.erase(iterbegin);
iterbegin = intlist.begin();
for (auto iter = intlist.begin(); iter != intlist.end(); ++iter)
intlist.clear();
for (auto iter = intlist.begin(); iter != intlist.end(); ++iter)
std::cout << std::endl;
//****************test shared ptr obj*********************************
stl::list>listobj;
std::cout << "listobj size :" << listobj.size() << std::endl;
std::cout << "test push_back():\n";
for (size_t i = 1; i < 6; i++)
for (auto iter = listobj.begin(); iter != listobj.end(); ++iter)
std::cout << std::endl;
std::cout << "test reverse():\n";
listobj.reverse();
for (auto iter = listobj.begin(); iter != listobj.end(); ++iter)
std::cout << std::endl;
auto iterbegin1 = listobj.begin();
listobj.erase(iterbegin1);
for (auto iter = listobj.begin(); iter != listobj.end(); ++iter)
std::cout << std::endl;
listobj.clear();
for (auto iter = listobj.begin(); iter != listobj.end(); ++iter)
std::cout << std::endl;
return 0;
}
控制台輸出:
STL原始碼分析之List
list是個環形雙向鍊錶,裡面的迭代器型別是bidirectional iterator tag,可以雙向移動,不想vector裡可以隨機訪問。同時刪除或新增結點對其他的迭代器無影響。list也有sort函式,我們知道sort函式只支援隨機訪問型迭代器,所有它的sort是自己另外宣告的。下面是原始碼...
STL原始碼剖析 list
相較於vector的連續線性空間,list就顯得複雜許多,它的好處是每次插入或刪除乙個元素,就配置或釋放乙個元素空間。因此,list對於空間的運用有絕對的精準,一點也不浪費。而且,對於任何位置的元素插入或元素移除,list永遠是常數時間。list不僅是乙個雙向鍊錶,而且還是乙個環狀雙向鍊錶。另外,還...
STL原始碼剖析 list!!!
list和vector是兩個最常被使用的容器。相較於vector的連續線性空間,list就顯得複雜許多,它的好處就是每次插入或刪除乙個元素,就配置或釋放乙個元素空間。而且對於任何位置的元素插入或元素移除,list永遠是常數時間。list是乙個雙向鍊錶,stl的list節點結構 template st...