C++ STL Container List
C++ STL Container List
List
- based on gnu 2.9
- 双向循环链表
Container
list node
1
2
3
4
5
6
7
template <class T>
struct __list_node {
typedef void* void_pointer;
void_pointer next;
void_pointer prev;
T data;
};
list
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
typedef void* void_pointer;
typedef __list_node<T> list_node;
typedef simple_alloc<list_node, Alloc> list_node_allocator;
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef list_node* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
*/
template <class T, class Alloc = alloc>
class list{
// 链表的尾节点
link_type node;
// iterator
iterator begin() { return (link_type)((*node).next); }
const_iterator begin() const { return (link_type)((*node).next); }
iterator end() { return node; }
const_iterator end() const { return node; }
reverse_iterator rbegin() { return reverse_iterator(end()); }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
// reference
reference front() { return *begin(); }
const_reference front() const { return *begin(); }
reference back() { return *(--end()); }
const_reference back() const { return *(--end()); }
// 容量
bool empty() const { return node->next == node; }
size_type size() const {
size_type result = 0;
distance(begin(), end(), result);
return result;
}
size_type max_size() const { return size_type(-1); }
// 插入节点
iterator insert(iterator position, const T& x) {
link_type tmp = create_node(x);
tmp->next = position.node;
tmp->prev = position.node->prev;
(link_type(position.node->prev))->next = tmp;
position.node->prev = tmp;
return tmp;
}
void push_front(const T& x) { insert(begin(), x); }
void push_back(const T& x) { insert(end(), x); }
// 删除节点
iterator erase(iterator position) {
link_type next_node = link_type(position.node->next);
link_type prev_node = link_type(position.node->prev);
prev_node->next = next_node;
next_node->prev = prev_node;
destroy_node(position.node);
return iterator(next_node);
}
void pop_front() { erase(begin()); }
void pop_back() {
iterator tmp = end();
erase(--tmp);
}
}
Iterator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
typedef __list_iterator<T, Ref, Ptr> self;
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef __list_node<T>* link_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
*/
template<class T, class Ref, class Ptr>
struct __list_iterator {
typedef bidirectional_iterator_tag iterator_category;
link_type node;
bool operator==(const self& x) const { return node == x.node; }
bool operator!=(const self& x) const { return node != x.node; }
reference operator*() const { return (*node).data; }
pointer operator->() const { return &(operator*()); }
// ++i
self& operator++() {
node = (link_type)((*node).next);
return *this;
}
// i++
// 后++调用前++
self operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
// --i
self& operator--() {
node = (link_type)((*node).prev);
return *this;
}
//i--
self operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
};
Algorithm
两个链表是否元素相同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template <class T, class Alloc>
bool operator==(const list<T,Alloc>& x, const list<T,Alloc>& y) {
// x和y的尾节点
link_type e1 = x.node;
link_type e2 = y.node;
// x和y的首节点
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){
if (n1->data != n2->data) return false;
}
// 是否都遍历完
return n1 == e1 && n2 == e2;
}
删除所有值为value的元素
1
2
3
4
5
6
7
8
9
10
11
12
template <class T, class Alloc>
void list<T, Alloc>::remove(const T& value) {
iterator first = begin();
iterator last = end();
while (first != last) {
iterator next = first;
++next;
if (*first == value) erase(first);
// 后移
first = next;
}
}
相邻元素去重
1
2
3
4
5
6
7
8
9
10
11
12
13
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) {
if (*first == *next) erase(next);
else first = next;
next = first;
}
}
将链表x按序合并到链表this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
transfer(position, first, last) {}
执行完后变成 position.prev->first->...->last->position->position->last
*/
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){
if (*first2 < *first1) {
iterator next = first2;
transfer(first1, first2, ++next);
first2 = next;
}
else ++first1;
}
if (first2 != last2) transfer(last1, first2, last2);
}
翻转链表
1
2
3
4
5
6
7
8
9
10
11
12
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;
// 相当于头插
transfer(begin(), old, first);
}
}
链表排序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 归并排序
// O(nlogn)
/*
this::splice(position, list, i)
将list链表中的i元素插入到this链表的position位置
*/
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];
int fill = 0;
while (!empty()) {
carry.splice(carry.begin(), *this, begin());
int i = 0;
// 第i个counter最多放2^i个元素
// 放满后移到下一个位置
while(i < fill && !counter[i].empty()) {
counter[i].merge(carry);
// carry.swap(counter[i++]);
carry.swap(counter[i]); i++;
}
// 遇到空counter, 将carry放到空的位置上, carry置空
carry.swap(counter[i]);
// fill+1, 此时前fill个counter为空, 再从第0个counter开始放
if (i == fill) ++fill;
}
// 归并所有counter
for (int i = 1; i < fill; ++i) counter[i].merge(counter[i-1]);
swap(counter[fill-1]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
算法流程模拟
*/
#include <iostream>
#include <list>
#include <vector>
#include <algorithm>
void printList(const std::list<int>& lst) {
for (auto it = lst.begin(); it != lst.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
void printCounters(const std::vector<std::list<int>>& counters, int fill) {
for (int i = 0; i < fill; ++i) {
std::cout << "counter[" << i << "]: ";
for (auto it = counters[i].begin(); it != counters[i].end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
}
}
void sortList(std::list<int>& lst) {
std::list<int> carry;
std::vector<std::list<int>> counter(64); // 64 empty lists
int fill = 0;
std::cout << "Initial list: ";
printList(lst);
std::cout << std::endl;
while (!lst.empty()) {
// Move the first element of lst to carry
carry.splice(carry.begin(), lst, lst.begin());
std::cout << "Moved to carry: ";
printList(carry);
std::cout << "Remaining list: ";
printList(lst);
std::cout << std::endl;
// Each counter[i] can hold up to fill elements, put carry into the first empty counter[i]
int i = 0;
while (i < fill && !counter[i].empty()) {
counter[i].merge(carry);
carry.swap(counter[i]);
++i;
}
carry.swap(counter[i]); // Ensure carry is empty after swapping
if (i == fill) ++fill;
std::cout << "After merge and swap: " << std::endl;
printCounters(counter, fill);
std::cout << std::endl;
}
// Merging all counters
for (int i = 1; i < fill; ++i) {
counter[0].merge(counter[i]);
}
carry.swap(counter[0]);
std::cout << "Final sorted list: ";
printList(carry);
}
int main() {
std::list<int> lst = {16,15,14,13,12,11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
sortList(lst);
return 0;
}
This post is licensed under CC BY 4.0 by the author.