STL原始碼分析 List

2021-10-09 11:56:05 字數 3945 閱讀 6379

鍊錶是一種線性表,但不會按照線性的順序儲存。鍊錶每次插入和刪除乙個元素,只配置或者釋放乙個元素空間,對於任何位置的元素的插入或者刪除,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...