SGISTL原始碼閱讀十三 list容器下
阿新 • • 發佈:2018-11-14
SGISTL原始碼閱讀十三 list容器下
前言
我們將繼續介紹list
的相關操作
深入原始碼
remove
remove
的作用是刪除指定值的節點
template <class T, class Alloc> void list<T, Alloc>::remove(const T& value) { iterator first = begin(); iterator last = end(); //遍歷list while (first != last) { iterator next = first; ++next; //如果當前節點的value為指定值,則刪除它 if (*first == value) erase(first); first = next; } }
unique()
該函式的作用是刪除值相同的連續的元素,直至該元素剩最後一個。
template <class T, class Alloc> void list<T, Alloc>::unique() { iterator first = begin(); iterator last = end(); if (first == last) return; iterator next = first; while (++next != last) { /* 比較前後兩個元素的值 * 若相等,則進行刪除 * 否則移動first迭代器,跟進到next */ if (*first == *next) erase(next); else first = next; /* 可能會因為erase刪除操作使next失效 * 所以需要更新next,保持與first指向相同元素 */ next = first; } }
merge
函式的作用是將list x合併到該list上,合併的順序是遞增排序,並且要求合併前,兩個list中的元素已經是遞增的。呼叫了前面提到過的transfer
函式
template <class T, class Alloc> void list<T, Alloc>::merge(list<T, Alloc>& x) { iterator first1 = begin(); iterator last1 = end(); iterator first2 = x.begin(); iterator last2 = x.end(); //兩個連結串列還沒到結尾 while (first1 != last1 && first2 != last2) /* 若*first2 < *first1 * 則將first2指向的元素移動到first1指向的元素前面 * 否則first1++,尋找下一個插入點 */ if (*first2 < *first1) { iterator next = first2; transfer(first1, first2, ++next); first2 = next; } else ++first1; /* 若first2 != last2 * 證明x的元素還沒全部被移動到list上 * 將剩餘的元素移動到last1前面 */ if (first2 != last2) transfer(last1, first2, last2); }
reverse
故名思意,這個函式的作用是將連結串列倒置
template <class T, class Alloc>
void list<T, Alloc>::reverse() {
//如果連結串列為空或者只有一個節點,則不用做任何操作
if (node->next == node || link_type(node->next)->next == node) return;
iterator first = begin();
++first;
while (first != end()) {
iterator old = first;
++first;
//利用前插法倒置,begin位置不動,把依次後面的元素插入到begin前面去
//插入結束後begin的位置是最後一個節點
transfer(begin(), old, first);
}
}
操作符過載
//過載=
template <class T, class Alloc>
list<T, Alloc>& list<T, Alloc>::operator=(const list<T, Alloc>& x) {
if (this != &x) {
iterator first1 = begin();
iterator last1 = end();
const_iterator first2 = x.begin();
const_iterator last2 = x.end();
//遍歷並且依次賦值
while (first1 != last1 && first2 != last2) *first1++ = *first2++;
//如果list比listx元素多,那麼刪除list中多餘元素
if (first2 == last2)
erase(first1, last1);
//如果list中空間不夠,則使用插入
else
insert(last1, first2, last2);
}
return *this;
}
//過載==
template <class T, class Alloc>
inline bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
typedef typename list<T,Alloc>::link_type link_type;
link_type e1 = x.node;
link_type e2 = y.node;
link_type n1 = (link_type) e1->next;
link_type n2 = (link_type) e2->next;
for ( ; n1 != e1 && n2 != e2 ; n1 = (link_type) n1->next, n2 = (link_type) n2->next)
//如果value不同直接返回false
if (n1->data != n2->data)
return false;
//若最後長度相等,就返回true,否則返回false
return n1 == e1 && n2 == e2;
}
//過載<
template <class T, class Alloc>
inline bool operator<(const list<T, Alloc>& x, const list<T, Alloc>& y) {
return lexicographical_compare(x.begin(), x.end(), y.begin(), y.end());
}
總結
我們繼續對list
相關操作進行了分析。
對list
的學習就到此結束了,接下來將繼續學習deque