拆分双重链表c++

Splitting Doubly linked list C++

本文关键字:c++ 链表 拆分      更新时间:2023-10-16

我想知道我是否能得到任何洞察力,为什么我得到错误:terminating with uncaught exception of type std::out_of_range: coordinates (400,0) outside valid range of [0, 399] X [0, 239]时,我运行以下代码。

该方法假定在传递给它的索引处分割DLL。因此,split(2)将以2个节点离开被调用的列表,而旧列表的其余部分将作为新列表返回。我尝试了很多不同的方法来写这个,但是没有一个有效(我们必须使用unique_ptrs来赋值)。

template <class T>
auto dl_list<T>::split(node* start, unsigned split_point)
    -> std::unique_ptr<node>
{
    assert(split_point > 0);
    if(start == nullptr)
        return nullptr;
    node* curr = start;
    uint64_t i = 0;
    while(i < split_point)
    {
    curr = (curr->next).get();
    i++;
   }
    std::unique_ptr<node> temp{nullptr};
    temp = std::move(curr->prev->next);
    (temp)->prev = nullptr;
    return temp;
}

如果有帮助,下面是包装器方法:

template <class T>
auto dl_list<T>::split(unsigned split_point) -> dl_list
{
if (split_point >= size_)
    return {};
if (split_point == 0)
{
    dl_list lst;
    swap(*this);
    return lst;
}
auto old_size = size_;
auto new_head = split(head_.get(), split_point);
// set up current list
size_ = split_point;
for (tail_ = head_.get(); tail_->next; tail_ = tail_->next.get())
    ;
// set up returned list
dl_list ret;
ret.head_ = std::move(new_head);
for (ret.tail_ = ret.head_.get(); ret.tail_->next;
     ret.tail_ = ret.tail_->next.get())
    ;
ret.size_ = old_size - split_point;
return ret;
}

以下代码用于在节点的左(前)侧取消指定节点和列表的其余部分的链接,假设总是存在前一个节点(即带有头节点的列表):

auto unlinked_list_from( Node* p )
    -> Node*
{
    p->prev->next = nullptr;
    p->prev = nullptr;
    return p;
}

查找n’节点是另一个问题。

结合两者,在找到n’节点并将其与列表的其余部分断开链接时,是一个更高级别的问题,其中使用两个较低级别的解决方案。


在链表或树的内部指针中使用std::unique_ptrstd::shared_ptr这样的智能指针通常不是一个好主意。从销毁责任的意义上说,并不是每个节点都拥有前一个和下一个节点。这是使用原始指针的情况。

但是,除了学习和高级编程之外,请使用标准库容器,如std::vector