STL原始碼分析之List

2021-10-01 23:08:40 字數 3917 閱讀 3456

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...