main
caoxin 7 months ago
parent 1d399c0a95
commit 5b839df1f8

@ -610,36 +610,66 @@ list<T>::erase(const_iterator first, const_iterator last)
} }
// 清空 list // 清空 list
/**
*
* 0
*
*
*
*
*/
template <class T> template <class T>
void list<T>::clear() void list<T>::clear()
{ {
// 如果列表不为空,则执行清除操作
if (size_ != 0) if (size_ != 0)
{ {
// 从第一个实际元素节点开始遍历(跳过头节点)
auto cur = node_->next; auto cur = node_->next;
// 用于临时存储下一个节点,以便在销毁当前节点后仍然可以访问它
for (base_ptr next = cur->next; cur != node_; cur = next, next = cur->next) for (base_ptr next = cur->next; cur != node_; cur = next, next = cur->next)
{ {
// 销毁当前节点,释放其内存
destroy_node(cur->as_node()); destroy_node(cur->as_node());
} }
// 断开头节点的链接,使其成为一个孤立的节点
node_->unlink(); node_->unlink();
// 将列表的大小设置为0
size_ = 0; size_ = 0;
} }
} }
// 重置容器大小 // 重置容器大小
/**
* new_sizevalue
* new_size
* new_sizenew_size
* value使new_size
*
* @param new_size
* @param value new_size
*/
template <class T> template <class T>
void list<T>::resize(size_type new_size, const value_type& value) void list<T>::resize(size_type new_size, const value_type& value)
{ {
// 获取列表的开始迭代器
auto i = begin(); auto i = begin();
// 初始化当前长度
size_type len = 0; size_type len = 0;
// 遍历列表,直到达到新的大小或列表末尾
while (i != end() && len < new_size) while (i != end() && len < new_size)
{ {
// 移动到下一个元素
++i; ++i;
// 增加当前长度
++len; ++len;
} }
// 如果当前长度等于新的大小,删除剩余的元素
if (len == new_size) if (len == new_size)
{ {
erase(i, node_); erase(i, node_);
} }
// 如果当前长度小于新的大小,插入新元素
else else
{ {
insert(node_, new_size - len, value); insert(node_, new_size - len, value);
@ -667,42 +697,78 @@ void list<T>::splice(const_iterator pos, list& x)
} }
// 将 it 所指的节点接合于 pos 之前 // 将 it 所指的节点接合于 pos 之前
/**
* xpos
* xitpos
* itpospos
*
* itxpos
*
*
* @param pos const_iterator
* @param x
* @param it const_iterator
*/
template <class T> template <class T>
void list<T>::splice(const_iterator pos, list& x, const_iterator it) void list<T>::splice(const_iterator pos, list& x, const_iterator it)
{ {
// 检查元素it是否不在pos之前或pos位置且两个列表不是同一个对象
if (pos.node_ != it.node_ && pos.node_ != it.node_->next) if (pos.node_ != it.node_ && pos.node_ != it.node_->next)
{ {
// 检查当前列表的大小是否会超过最大限制
THROW_LENGTH_ERROR_IF(size_ > max_size() - 1, "list<T>'s size too big"); THROW_LENGTH_ERROR_IF(size_ > max_size() - 1, "list<T>'s size too big");
// 获取要移动的节点
auto f = it.node_; auto f = it.node_;
// 从列表x中解链节点f
x.unlink_nodes(f, f); x.unlink_nodes(f, f);
// 将节点f链接到当前列表的pos位置
link_nodes(pos.node_, f, f); link_nodes(pos.node_, f, f);
// 更新当前列表和列表x的大小
++size_; ++size_;
--x.size_; --x.size_;
} }
} }
// 将 list x 的 [first, last) 内的节点接合于 pos 之前 // 将 list x 的 [first, last) 内的节点接合于 pos 之前
/**
* x[first, last)pos
* xpos
*
*
* xpos
*
*
* @param pos const_iterator
* @param x
* @param first const_iterator
* @param last const_iterator
*/
template <class T> template <class T>
void list<T>::splice(const_iterator pos, list& x, const_iterator first, const_iterator last) void list<T>::splice(const_iterator pos, list& x, const_iterator first, const_iterator last)
{ {
// 检查区间是否有效且两个列表不是同一个对象
if (first != last && this != &x) if (first != last && this != &x)
{ {
// 计算区间中的元素数量
size_type n = mystl::distance(first, last); size_type n = mystl::distance(first, last);
// 检查当前列表的大小是否会超过最大限制
THROW_LENGTH_ERROR_IF(size_ > max_size() - n, "list<T>'s size too big"); THROW_LENGTH_ERROR_IF(size_ > max_size() - n, "list<T>'s size too big");
// 获取区间的头节点和尾节点的前一个节点
auto f = first.node_; auto f = first.node_;
auto l = last.node_->prev; auto l = last.node_->prev;
// 从列表x中解链该区间
x.unlink_nodes(f, l); x.unlink_nodes(f, l);
// 将解链的区间链接到当前列表的pos位置
link_nodes(pos.node_, f, l); link_nodes(pos.node_, f, l);
// 更新当前列表和列表x的大小
size_ += n; size_ += n;
x.size_ -= n; x.size_ -= n;
} }
} }
// 将另一元操作 pred 为 true 的所有元素移除 // 将另一元操作 pred 为 true 的所有元素移除
template <class T> template <class T>
template <class UnaryPredicate> template <class UnaryPredicate>
@ -745,24 +811,40 @@ void list<T>::unique(BinaryPredicate pred)
} }
// 与另一个 list 合并,按照 comp 为 true 的顺序 // 与另一个 list 合并,按照 comp 为 true 的顺序
/**
* 使
* xcomp
*
* x
* xcompx
* x
*
* @param x
* @param comp
*/
template <class T> template <class T>
template <class Compare> template <class Compare>
void list<T>::merge(list& x, Compare comp) void list<T>::merge(list& x, Compare comp)
{ {
// 确保合并的两个列表不是同一个对象
if (this != &x) if (this != &x)
{ {
// 检查合并后的列表大小是否会超过最大限制
THROW_LENGTH_ERROR_IF(size_ > max_size() - x.size_, "list<T>'s size too big"); THROW_LENGTH_ERROR_IF(size_ > max_size() - x.size_, "list<T>'s size too big");
// 获取当前列表的开始和结束迭代器
auto f1 = begin(); auto f1 = begin();
auto l1 = end(); auto l1 = end();
// 获取要合并的列表的开始和结束迭代器
auto f2 = x.begin(); auto f2 = x.begin();
auto l2 = x.end(); auto l2 = x.end();
// 遍历两个列表,合并元素
while (f1 != l1 && f2 != l2) while (f1 != l1 && f2 != l2)
{ {
if (comp(*f2, *f1)) if (comp(*f2, *f1))
{ {
// 使 comp 为 true 的一段区间 // 找到x中第一个大于或等于f1的元素区间
auto next = f2; auto next = f2;
++next; ++next;
for (; next != l2 && comp(*next, *f1); ++next) for (; next != l2 && comp(*next, *f1); ++next)
@ -771,7 +853,7 @@ void list<T>::merge(list& x, Compare comp)
auto l = next.node_->prev; auto l = next.node_->prev;
f2 = next; f2 = next;
// link node // 从x中解链该区间并将其链接到当前列表的适当位置
x.unlink_nodes(f, l); x.unlink_nodes(f, l);
link_nodes(f1.node_, f, l); link_nodes(f1.node_, f, l);
++f1; ++f1;
@ -781,7 +863,7 @@ void list<T>::merge(list& x, Compare comp)
++f1; ++f1;
} }
} }
// 连接剩余部分 // 如果x中还有剩余的元素将它们连接到当前列表的末尾
if (f2 != l2) if (f2 != l2)
{ {
auto f = f2.node_; auto f = f2.node_;
@ -790,26 +872,41 @@ void list<T>::merge(list& x, Compare comp)
link_nodes(l1.node_, f, l); link_nodes(l1.node_, f, l);
} }
// 更新当前列表的大小x列表的大小设置为0
size_ += x.size_; size_ += x.size_;
x.size_ = 0; x.size_ = 0;
} }
} }
// 将 list 反转 // 将 list 反转
/**
*
*
*
*
*
*/
template <class T> template <class T>
void list<T>::reverse() void list<T>::reverse()
{ {
// 如果列表为空或只包含一个元素,则不需要反转
if (size_ <= 1) if (size_ <= 1)
{ {
return; return;
} }
// 获取列表的开始迭代器
auto i = begin(); auto i = begin();
// 获取列表的结束迭代器
auto e = end(); auto e = end();
// 遍历列表,直到到达最后一个节点
while (i.node_ != e.node_) while (i.node_ != e.node_)
{ {
// 交换当前节点的前后指针
mystl::swap(i.node_->prev, i.node_->next); mystl::swap(i.node_->prev, i.node_->next);
// 移动到下一个节点,即原前一个节点
i.node_ = i.node_->prev; i.node_ = i.node_->prev;
} }
// 处理最后一个节点,将其前后指针交换
mystl::swap(e.node_->prev, e.node_->next); mystl::swap(e.node_->prev, e.node_->next);
} }
@ -817,26 +914,39 @@ void list<T>::reverse()
// helper function // helper function
// 创建结点 // 创建结点
/**
*
* 使
*
*
* @param args
* @return
*/
template <class T> template <class T>
template <class ...Args> template <class ...Args>
typename list<T>::node_ptr typename list<T>::node_ptr
list<T>::create_node(Args&& ...args) list<T>::create_node(Args&& ...args)
{ {
// 分配一个新的节点
node_ptr p = node_allocator::allocate(1); node_ptr p = node_allocator::allocate(1);
try try
{ {
// 使用完美转发构造节点中的值
data_allocator::construct(mystl::address_of(p->value), mystl::forward<Args>(args)...); data_allocator::construct(mystl::address_of(p->value), mystl::forward<Args>(args)...);
// 初始化节点的prev和next指针
p->prev = nullptr; p->prev = nullptr;
p->next = nullptr; p->next = nullptr;
} }
catch (...) catch (...)
{ {
// 如果构造过程中发生异常,释放已分配的节点
node_allocator::deallocate(p); node_allocator::deallocate(p);
// 重新抛出异常
throw; throw;
} }
// 返回指向新创建节点的指针
return p; return p;
} }
// 销毁结点 // 销毁结点
template <class T> template <class T>
void list<T>::destroy_node(node_ptr p) void list<T>::destroy_node(node_ptr p)
@ -846,75 +956,125 @@ void list<T>::destroy_node(node_ptr p)
} }
// 用 n 个元素初始化容器 // 用 n 个元素初始化容器
/**
* nvalue
* nvalue
* nvalue
*
*/
template <class T> template <class T>
void list<T>::fill_init(size_type n, const value_type& value) void list<T>::fill_init(size_type n, const value_type& value)
{ {
// 分配一个新的节点作为列表的头节点
node_ = base_allocator::allocate(1); node_ = base_allocator::allocate(1);
// 将头节点从链表中解链,使其成为一个独立的节点
node_->unlink(); node_->unlink();
// 设置列表的大小为n
size_ = n; size_ = n;
// 尝试创建n个新节点并将它们链接到链表的末尾
try try
{ {
for (; n > 0; --n) for (; n > 0; --n)
{ {
// 创建一个新节点包含给定的值value
auto node = create_node(value); auto node = create_node(value);
// 将新创建的节点链接到链表的末尾
link_nodes_at_back(node->as_base(), node->as_base()); link_nodes_at_back(node->as_base(), node->as_base());
} }
} }
catch (...) catch (...)
{ {
// 如果在创建节点或链接过程中发生异常,执行清理操作
clear(); clear();
// 释放之前分配的头节点
base_allocator::deallocate(node_); base_allocator::deallocate(node_);
// 将头节点指针设置为nullptr表示链表为空
node_ = nullptr; node_ = nullptr;
// 重新抛出捕获的异常
throw; throw;
} }
} }
// 以 [first, last) 初始化容器 // 以 [first, last) 初始化容器
/**
*
* [first, last)
*
*
*
*
* @param first
* @param last
*/
template <class T> template <class T>
template <class Iter> template <class Iter>
void list<T>::copy_init(Iter first, Iter last) void list<T>::copy_init(Iter first, Iter last)
{ {
// 分配一个新的节点作为列表的头节点
node_ = base_allocator::allocate(1); node_ = base_allocator::allocate(1);
// 将头节点从链表中解链,使其成为一个独立的节点
node_->unlink(); node_->unlink();
// 计算迭代器范围内元素的数量
size_type n = mystl::distance(first, last); size_type n = mystl::distance(first, last);
// 设置列表的大小为计算出的元素数量
size_ = n; size_ = n;
// 尝试创建节点并链接到链表的末尾
try try
{ {
for (; n > 0; --n, ++first) for (; n > 0; --n, ++first)
{ {
// 创建一个新节点,包含迭代器指向的值
auto node = create_node(*first); auto node = create_node(*first);
// 将新创建的节点链接到链表的末尾
link_nodes_at_back(node->as_base(), node->as_base()); link_nodes_at_back(node->as_base(), node->as_base());
} }
} }
catch (...) catch (...)
{ {
// 如果在创建节点或链接过程中发生异常,执行清理操作
clear(); clear();
// 释放之前分配的头节点
base_allocator::deallocate(node_); base_allocator::deallocate(node_);
// 将头节点指针设置为nullptr表示链表为空
node_ = nullptr; node_ = nullptr;
// 重新抛出捕获的异常
throw; throw;
} }
} }
// 在 pos 处连接一个节点 // 在 pos 处连接一个节点
t/**
* pos
* poslink_node
* posnode_
* pos
* pos
*
* @param pos const_iterator
* @param link_node base_ptr
* @return iterator
*/
template <class T> template <class T>
typename list<T>::iterator typename list<T>::iterator
list<T>::link_iter_node(const_iterator pos, base_ptr link_node) list<T>::link_iter_node(const_iterator pos, base_ptr link_node)
{ {
// 如果pos是头节点的下一个节点将新节点链接在列表的开头
if (pos == node_->next) if (pos == node_->next)
{ {
link_nodes_at_front(link_node, link_node); link_nodes_at_front(link_node, link_node);
} }
// 如果pos是头节点将新节点链接在列表的末尾
else if (pos == node_) else if (pos == node_)
{ {
link_nodes_at_back(link_node, link_node); link_nodes_at_back(link_node, link_node);
} }
// 否则将新节点链接在pos指定的位置
else else
{ {
link_nodes(pos.node_, link_node, link_node); link_nodes(pos.node_, link_node, link_node);
} }
// 返回一个迭代器,指向新链接的节点
return iterator(link_node); return iterator(link_node);
} }
// 在 pos 处连接 [first, last] 的结点 // 在 pos 处连接 [first, last] 的结点
template <class T> template <class T>
void list<T>::link_nodes(base_ptr pos, base_ptr first, base_ptr last) void list<T>::link_nodes(base_ptr pos, base_ptr first, base_ptr last)
@ -954,19 +1114,34 @@ void list<T>::unlink_nodes(base_ptr first, base_ptr last)
} }
// 用 n 个元素为容器赋值 // 用 n 个元素为容器赋值
/**
* valuen
* nn
* nvaluen
* valuen
* ninsertvalue
* nerase
*
* @param n
* @param value
*/
template <class T> template <class T>
void list<T>::fill_assign(size_type n, const value_type& value) void list<T>::fill_assign(size_type n, const value_type& value)
{ {
// 获取列表的开始和结束迭代器
auto i = begin(); auto i = begin();
auto e = end(); auto e = end();
// 遍历列表将元素赋值为value直到达到n个元素或遍历完整个列表
for (; n > 0 && i != e; --n, ++i) for (; n > 0 && i != e; --n, ++i)
{ {
*i = value; *i = value;
} }
// 如果n大于当前列表大小需要在列表末尾插入剩余的value元素
if (n > 0) if (n > 0)
{ {
insert(e, n, value); insert(e, n, value);
} }
// 如果n小于当前列表大小需要删除多余的元素
else else
{ {
erase(i, e); erase(i, e);
@ -974,20 +1149,34 @@ void list<T>::fill_assign(size_type n, const value_type& value)
} }
// 复制[f2, l2)为容器赋值 // 复制[f2, l2)为容器赋值
/**
*
* [f2, l2)
* f2f2l2
* f2l2
* f2l2
*
* @param f2
* @param l2
*/
template <class T> template <class T>
template <class Iter> template <class Iter>
void list<T>::copy_assign(Iter f2, Iter l2) void list<T>::copy_assign(Iter f2, Iter l2)
{ {
// 获取列表的开始和结束迭代器
auto f1 = begin(); auto f1 = begin();
auto l1 = end(); auto l1 = end();
// 遍历列表将元素赋值为迭代器f2指向的元素
for (; f1 != l1 && f2 != l2; ++f1, ++f2) for (; f1 != l1 && f2 != l2; ++f1, ++f2)
{ {
*f1 = *f2; *f1 = *f2;
} }
// 如果f2到达l2说明新内容比原列表短删除列表中剩余的元素
if (f2 == l2) if (f2 == l2)
{ {
erase(f1, l1); erase(f1, l1);
} }
// 如果f2没有到达l2说明新内容比原列表长在列表末尾插入剩余的元素
else else
{ {
insert(l1, f2, l2); insert(l1, f2, l2);
@ -995,6 +1184,19 @@ void list<T>::copy_assign(Iter f2, Iter l2)
} }
// 在 pos 处插入 n 个元素 // 在 pos 处插入 n 个元素
/**
* nvalue
* posnvalue
* n0value
* n-1
*
* pos
*
* @param pos const_iterator
* @param n
* @param value
* @return iterator
*/
template <class T> template <class T>
typename list<T>::iterator typename list<T>::iterator
list<T>::fill_insert(const_iterator pos, size_type n, const value_type& value) list<T>::fill_insert(const_iterator pos, size_type n, const value_type& value)
@ -1016,10 +1218,12 @@ list<T>::fill_insert(const_iterator pos, size_type n, const value_type& value)
end.node_->next = next->as_base(); // link node end.node_->next = next->as_base(); // link node
next->prev = end.node_; next->prev = end.node_;
} }
// 更新列表的大小
size_ += add_size; size_ += add_size;
} }
catch (...) catch (...)
{ {
// 如果发生异常,清理已创建的节点
auto enode = end.node_; auto enode = end.node_;
while (true) while (true)
{ {
@ -1029,14 +1233,28 @@ list<T>::fill_insert(const_iterator pos, size_type n, const value_type& value)
break; break;
enode = prev; enode = prev;
} }
// 重新抛出异常
throw; throw;
} }
// 将新创建的节点序列链接到列表的pos位置
link_nodes(pos.node_, r.node_, end.node_); link_nodes(pos.node_, r.node_, end.node_);
} }
return r; return r;
} }
// 在 pos 处插入 [first, last) 的元素 // 在 pos 处插入 [first, last) 的元素
/**
* nfirst
* posnfirst
* n0*first
* n-1
*
* pos
*
* @param pos const_iterator
* @param n
* @param first
* @return iterator
*/
template <class T> template <class T>
template <class Iter> template <class Iter>
typename list<T>::iterator typename list<T>::iterator
@ -1052,16 +1270,19 @@ list<T>::copy_insert(const_iterator pos, size_type n, Iter first)
iterator end = r; iterator end = r;
try try
{ {
// 从first开始创建n个节点
for (--n, ++first; n > 0; --n, ++first, ++end) for (--n, ++first; n > 0; --n, ++first, ++end)
{ {
auto next = create_node(*first); auto next = create_node(*first);
end.node_->next = next->as_base(); // link node end.node_->next = next->as_base(); // link node
next->prev = end.node_; next->prev = end.node_;
} }
// 更新列表的大小
size_ += add_size; size_ += add_size;
} }
catch (...) catch (...)
{ {
// 如果发生异常,清理已创建的节点
auto enode = end.node_; auto enode = end.node_;
while (true) while (true)
{ {
@ -1071,14 +1292,28 @@ list<T>::copy_insert(const_iterator pos, size_type n, Iter first)
break; break;
enode = prev; enode = prev;
} }
// 重新抛出异常
throw; throw;
} }
// 将新创建的节点序列链接到列表的pos位置
link_nodes(pos.node_, r.node_, end.node_); link_nodes(pos.node_, r.node_, end.node_);
} }
return r; return r;
} }
// 对 list 进行归并排序,返回一个迭代器指向区间最小元素的位置 // 对 list 进行归并排序,返回一个迭代器指向区间最小元素的位置
/**
*
* 使
* 2
* 2
* 2
*
* @param f1
* @param l2
* @param n
* @param comp
* @return
*/
template <class T> template <class T>
template <class Compared> template <class Compared>
typename list<T>::iterator typename list<T>::iterator
@ -1102,8 +1337,8 @@ list<T>::list_sort(iterator f1, iterator l2, size_type n, Compared comp)
auto n2 = n / 2; auto n2 = n / 2;
auto l1 = f1; auto l1 = f1;
mystl::advance(l1, n2); mystl::advance(l1, n2);
auto result = f1 = list_sort(f1, l1, n2, comp); // 前半段的最小位置 auto result = f1 = list_sort(f1, l1, n2, comp); // 对前半段进行排序,找到最小元素的位置
auto f2 = l1 = list_sort(l1, l2, n - n2, comp); // 后半段的最小位置 auto f2 = l1 = list_sort(l1, l2, n - n2, comp); // 对后半段进行排序,找到最小元素的位置
// 把较小的一段区间移到前面 // 把较小的一段区间移到前面
if (comp(*f2, *f1)) if (comp(*f2, *f1))
@ -1154,7 +1389,6 @@ list<T>::list_sort(iterator f1, iterator l2, size_type n, Compared comp)
} }
return result; return result;
} }
// 重载比较操作符 // 重载比较操作符
template <class T> template <class T>
bool operator==(const list<T>& lhs, const list<T>& rhs) bool operator==(const list<T>& lhs, const list<T>& rhs)

Loading…
Cancel
Save