list是個環形雙向鍊錶,裡面的迭代器型別是bidirectional_iterator_tag,可以雙向移動,不想vector裡可以隨機訪問。同時刪除或新增結點對其他的迭代器無影響。list也有sort函式,我們知道sort函式只支援隨機訪問型迭代器,所有它的sort是自己另外宣告的。下面是原始碼分析,基本都標註了各函式功能和分析
template struct __list_node //鍊錶節點
;template//使結點能進行->,*等操作
struct __list_iterator
__list_iterator() {}
__list_iterator(const iterator& x) : node(x.node) {}
//運算子過載
bool operator==(const self& x) const
bool operator!=(const self& x) const
// 對迭代器取值,取的是節點的資料值
reference operator*() const
// 指向迭代器就是指向其資料
pointer operator->() const
// 迭代器後移
self& operator++()
self operator++(int)
// 前移
self& operator--()
self operator--(int)
};template class list
//釋放乙個結點
void put_node(link_type p)
//構造結點
link_type create_node(const t& x)
// 析構結點元素, 並釋放記憶體
void destroy_node(link_type p)
protected:
// 初始化時申請了乙個空結點
void empty_initialize()
// 建立值為value共n個結點的鍊錶
void fill_initialize(size_type n, const t& value)
__stl_unwind(clear(); put_node(node));
}public:
list()
//從頭結點的下乙個開始
iterator begin()
//返回頭結點(環形鍊錶)
iterator end()
// 頭結點指向自身說明鍊錶中無元素
bool empty() const
// 使用distance()進行計算, 時間複雜度o(n)
size_type size() const
size_type max_size() const
reference front()
reference back()
iterator insert(iterator position, const t& x)
//連續插入幾個結點
void insert(iterator pos, size_type n, const t& x);
void insert(iterator pos, int n, const t& x)
void insert(iterator pos, long n, const t& x)
// 在鍊錶前端插入結點
void push_front(const t& x)
// 在鍊錶最後插入結點
void push_back(const t& x)
// 移除迭代器position所指節點,注意移除後其他結點迭代器任有效
iterator erase(iterator position)
iterator erase(iterator first, iterator last);
void resize(size_type new_size, const t& x);
void resize(size_type new_size)
void clear();
// 刪除鍊錶第乙個結點
void pop_front()
// 刪除鍊錶最後乙個結點
void pop_back()
list(size_type n, const t& value)
list(int n, const t& value)
list(long n, const t& value)
~list()
clear();
// 釋放頭結點
put_node(node);
}list& operator=(const list& x);
protected:
//將[first, last)範圍內的元素移動到position前
void transfer(iterator position, iterator first, iterator last)
}public:
// 將鍊錶x移動到position所指位置之前
void splice(iterator position, list& x)
// 將鍊錶中i指向的內容移動到position之前
void splice(iterator position, list&, iterator i)
// 將鍊錶[first, last}元素移動到position之前
void splice(iterator position, list&, iterator first, iterator last)
void remove(const t& value);
void unique();
void merge(list& x);
void reverse();
void sort();
};// 銷毀所有結點, 將鍊錶置空
template void list::clear()
node->next = node;
node->prev = node;
}//鍊錶直接賦值
template list& list::operator=(const list& x)
return *this;
}//將相鄰的重複的點去掉
template void list::unique()
}template void list::merge(list& x)
else
++first1;
if (first2 != last2)
transfer(last1, first2, last2);
}
來簡單實踐下它的操作函式
#include #include #include using namespace std;
void print(lists)
coutprint(s);
s.insert(s.begin(),4); //注意不能寫成s.begin()+n
print(s);
vectorss;
s.insert(s.begin(),ss.begin(),ss.end()); //可以在鍊錶中加上任意容器元素
print(s);
//?不能直接呼叫?
lists1(5,7);
//insert是建立新的結點,splice是直接將原來的結點交接到這個鍊錶後面
s.splice(s.end(),s1); //將鍊錶拼接在迭代器後
print(s);
s.reverse();
print(s);
s.sort();
print(s);
return 0;
}
STL原始碼分析 List
鍊錶是一種線性表,但不會按照線性的順序儲存。鍊錶每次插入和刪除乙個元素,只配置或者釋放乙個元素空間,對於任何位置的元素的插入或者刪除,list永遠是常量時間複雜度。template struct listnode 節點物件包含兩個節點物件指標,分別指向前乙個節點和後乙個節點,還有乙個節點物件存放的資...
STL原始碼剖析 list
相較於vector的連續線性空間,list就顯得複雜許多,它的好處是每次插入或刪除乙個元素,就配置或釋放乙個元素空間。因此,list對於空間的運用有絕對的精準,一點也不浪費。而且,對於任何位置的元素插入或元素移除,list永遠是常數時間。list不僅是乙個雙向鍊錶,而且還是乙個環狀雙向鍊錶。另外,還...
STL原始碼剖析 list!!!
list和vector是兩個最常被使用的容器。相較於vector的連續線性空間,list就顯得複雜許多,它的好處就是每次插入或刪除乙個元素,就配置或釋放乙個元素空間。而且對於任何位置的元素插入或元素移除,list永遠是常數時間。list是乙個雙向鍊錶,stl的list節點結構 template st...