向双向链表中插入数据并对数据进行排序

Inserting data into a double linked list and sorting the data

我想在一个排序的链表中以排序的方式插入数据。我能够插入数据,但它没有排序。谁能帮我解决我做错了什么? 这是我的功能:

typename SortedList<T>::iterator SortedList<T>::insert(const T& data) {


if (data < front_->data_) {
    Node* n = new Node(data, front_, nullptr);

    //if empty
    if (front_ == nullptr) {
        //make back pt to node
        back_ = n;
    }
    else {
        //make front's previous point to node
        front_->prev_ = n;
    }
    //make front point at node
    front_ = n;
    return SortedList<T>::iterator(n);
}
else {
    Node* nn = new Node(data, nullptr, back_);

    //if empty
    if (front_ == nullptr) {
        //make front_ pt to node
        front_ = nn;
    }
    else {
        //make back's next point to node
        back_->next_ = nn;
    }
    //make back point at node
    back_ = nn;
    return SortedList<T>::iterator(nn);
}

这是我的 class

class SortedList{

struct Node {
    T data_;
    Node* next_;
    Node* prev_;
    Node(const T& data = T{}, Node* nx = nullptr, Node* pr = nullptr) {
        data_ = data;
        next_ = nx;
        prev_ = pr;
    }
};

Node* front_;
Node* back_;
int sizelist;

}

您在访问 front_->data 之前没有检查 front_ 是否有 nullptr

但更重要的是,您没有尝试将数据插入任何类型的排序位置。您仅在列表的最前面或最后面插入。要在中间插入,您必须扫描列表以查找要插入的正确位置。

尝试更像这样的东西:

class SortedList{

    struct Node {
        T data_;
        Node* prev_;
        Node* next_;

        Node(const T& data = T{}, Node* pr = nullptr, Node* nx = nullptr)
            : data_(data), prev_(pr), next_(nx)
        {
        }
    };

    Node* front_;
    Node* back_;
    int size_;

    ...

    iterator insert(const T& data);
};

typename SortedList<T>::iterator SortedList<T>::insert(const T& data)
{
    Node *nn = front_;
    while ((nn) && (data >= nn->data_)) {
        nn = nn->next_;
    }

    Node *n = new Node(data);
    if (nn)
    {
        n->prev_ = nn->prev_;
        n->next_ = nn;
        if (nn->prev_) nn->prev_->next = n;
        nn->prev = n;
    }
    else
    {
        n->prev_ = back_;
        if (back_) back_->next_ = n;
        back_ = n;
    }

    if (front_ == nn) front_ = n;

    ++size_;

    return iterator(n);
}

我没有看到任何搜索列表以查找元素插入位置的代码。您没有指定您希望拥有的元素数量;线性插入排序列表的性能平均为 O(n/2),这导致您总体上将拥有 O(n^2/2) [即 n 平方超过 2] 的结论如果 n 是 10,000 是无法容忍的,如果 n < 10 则无关紧要。20 年前,我在 8088 上遇到过这个问题,n > 200。有一个大约为 O(log2(n)) 的解决方案,但不知道n 不相关的我不想花时间去解释

您的代码表明您的思路不够清晰。

您必须处理以下情况:

  1. 列表为空。
  2. 新数据小于列表中所有项目的值。
  3. 新数据大于列表中所有项目的值。
  4. 新数据介于列表中项目的最低值和最高值之间。

此外,您对 "prev" 和 "next" 的使用对我来说似乎有点奇怪。当我想到双向链表时,我认为它是:

          front -> next -> next -> next -> nullptr
nullptr <- prev <- prev <- prev <- back

您似乎在使用:

          front -> prev -> prev -> prev -> nullptr
nullptr <- next <- next <- next <- back

我的回答符合我认为你使用的第二个版本。如果那不正确,"next" 和 "prev" 的用法需要在几个地方更新。

案例一

在函数开头添加以下内容:

if ( front_ == nullptr )
{
   Node* n = new Node(data, nullptr, nullptr);
   front_ = n;
   back_ = n;
   return SortedList<T>::iterator(n);
}

案例二

你需要:

if ( data < front_->data_ )
{
   Node* n = new Node(data, front_, nullptr);
   front_->prev_ = n;
   return SortedList<T>::iterator(n);
}

案例三

你需要:

if ( data > back_->data_ )
{
   Node* n = new Node(data, nullptr, back_);
   back_->next_ = n;
   return SortedList<T>::iterator(n);
}

案例4

你需要:

// Find the place where to insert the new Node.
Node* iter = front_;
for ( ; iter != nullptr && data < iter->data_; iter = iter->prev_ );

// Insert the new Node.
Node* prev = iter->prev_
Node* n = new Node(data, iter, prev);
prev->next_ = n;
iter->prev_ = n;
return SortedList<T>::iterator(n);

放在一起:

typename SortedList<T>::iterator SortedList<T>::insert(const T& data)
{
   // Case 1
   if ( front_ == nullptr )
   {
      Node* n = new Node(data, nullptr, nullptr);
      front_ = n;
      back_ = n;
      return SortedList<T>::iterator(n);
   }

   // Case 2
   if ( data < front_->data_ )
   {
      Node* n = new Node(data, front_, nullptr);
      front_->prev_ = n;
      return SortedList<T>::iterator(n);
   }

   // Case 3
   if ( data > back_->data_ )
   {
      Node* n = new Node(data, nullptr, back_);
      back_->next_ = n;
      return SortedList<T>::iterator(n);
   }

   // Case 4

   // Find the place where to insert the new Node.
   Node* iter = front_;
   for ( ; iter != nullptr && data < iter->data_; iter = iter->prev_ );

   // Insert the new Node.
   Node* prev = iter->prev_
   Node* n = new Node(data, iter, prev);
   prev->next_ = n;
   iter->prev_ = n;
   return SortedList<T>::iterator(n);
}