main
caoxin 7 months ago
parent 1d399c0a95
commit 5b839df1f8

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

Loading…
Cancel
Save