C++ STL list操作,list採用link存儲,參考資料(侯捷,STL源碼剖析)
- list 使用雙向環狀鏈表形式,環狀鏈表只需一個標記,所以可以在鏈表尾端插入一個空白節點,使之符合STL前閉後開的規範
- list的主要操作transfer,移動元素的位置,splice基於transfer實現
// 將[first, last)內的所有元素移動到position之前, .操作符的優先級 > *操作符
/*
template<class T>
struct iterator{
link_type<T>* node;
};
template<class T>
struct node{
T data;
node<T>* next;
node<T>* prev;
};
*/
void transfer(iterator position, iterator first, iterator last){
if(position != last){
(last.node)->prev->next = position.node; //1
(first.node)->prev->next = last.node; //2
(position.node->prev->next) = first.node;//3
link_type tmp = link_type((position.node)->prev); //4
(position.node)->prev = (last.node)->prev; //5
(last.node)->prev = (first.node)->prev; //6
(first.node)->prev = tmp; //7
}
}
- 對list中元素進行排序的代碼如下:
template <class T, class Alloc>
void list<T, Alloc>::sort(){
// 判斷,若是空鏈表或者僅有一個元素,就不進行任何操作
if(node->next == node || link_type(node->next)->next == node)
return;
// 使用額外的中介數據存放區
list<T, Alloc> carry;
list<T, Alloc> counter[64]; // 差不多可排序2^64個元素
int fill=0;
while(!empty()){
carry.splice(carry.begin(), *this, begin()); // 將this的第一個元素移到carry中, 不太清楚*this具體指的是什麼
int i=0;
while(i<fill && !counter[i].empty()){
counter[i].merge(carry); // 將counter和carry的元素進行merge操作,存儲到counter中
carry.swap(counter[i++]); // 減counter的元素轉存到carry中
// 個人覺得這裏可以直接carry.merge(counter[i++]);
}
carry.swap(counter[i]); //carry中的元素轉存到counter中
if(i==fill) ++fill;
}
// 最後對全體的counter進行merge
for(int i=1; i<fill; ++i){
counter[i].merge(counter[i-1])
}
swap(counter[fill-1]); // this->swap(counter[fill-1]);
}