双链表插入项算法有缺陷

Double-linked-list insert item algorithm flawed

本文关键字:算法 有缺陷 插入 链表      更新时间:2023-10-16

我写了一个双链表:

class doubled {
private:
  class sublink {
  private:
    char data[30];
    sublink *next_ptr;
    sublink *previous_ptr;
    friend doubled;
  };
public:
  sublink *first_ptr;
  doubled(){first_ptr = NULL;};
  void add_item(char *item);
  void rm_item(char *item);
};

问题在于向列表中添加项目的函数:

void doubled::add_item(char *item){
  sublink *new_data;
  sublink *n_insert;
  sublink *p_insert;
  new_data = new sublink;
  n_insert = new sublink;
  p_insert = new sublink;
  if(first_ptr == NULL){
    strcpy(new_data->data, item);
    new_data->previous_ptr = NULL;
    new_data->next_ptr = first_ptr;
    first_ptr = new_data;
  } else {
    strcpy(new_data->data, item);
    n_insert = first_ptr;
    while(1){
      n_insert = n_insert->next_ptr;
      if(n_insert == NULL)
        break;
      if(strcmp(n_insert->data, new_data->data) >= 0){
        new_data->next_ptr = n_insert;
        n_insert->previous_ptr = new_data;
      }
    }
    p_insert = first_ptr;
    while(1){
      p_insert = p_insert->next_ptr;
      if(p_insert == NULL)
        break;
      if((strcmp(p_insert->data, new_data->data)) < 0){
        new_data->previous_ptr = p_insert;
        p_insert->next_ptr = new_data;
      }
    }
  }
  std::cout << first_ptr->data << 'n';
  std::cout << new_data->data << 'n';
  if(new_data->next_ptr != NULL)
    std::cout << new_data->next_ptr->data << 'n';
}

上面的代码按字母顺序将给定的项插入到列表中。

程序输出first_ptr->datanew_data->data,但不输出new_data->next_ptr->data,也不输出first_ptr->next_ptr->data。因此,语句if(new_data->next_ptr != NULL)总是为真,而不应该为真。

有人看到这个程序的问题了吗?

您可能忘记将前一个或下一个ptr设置为NULL。

在这里我修复了一点逻辑,并摆脱了段错误(我试图尽可能地评论每个被检查的情况):

#include <iostream>
#include <string.h>
class doubled 
{
private:
    class sublink 
    {
    private:
        char data[30];
        sublink *next_ptr;
        sublink *previous_ptr;
        friend doubled;
    };
public:
    sublink *first_ptr;
    doubled(){first_ptr = NULL;};
    void add_item(char *item);
    void rm_item(char *item);
};
void doubled::add_item(char *item)
{
    sublink *new_data;
    new_data = new sublink;
    strcpy(new_data->data, item);
    // empty list case
    if(first_ptr == NULL)
    {
        // Only item in the list, I have no next or previous element
        new_data->previous_ptr = NULL;
        new_data->next_ptr = NULL;
        // Make the list point to this element
        first_ptr = new_data;
    } 
    else 
    {
        sublink* iter;
        iter = first_ptr;
        // 1 element list
        if(iter->next_ptr == NULL)
        {
            // I'm after the first and only node
            if(strcmp(iter->data, new_data->data) <= 0)
            {
                iter->next_ptr = new_data;
                new_data->previous_ptr = iter;
                new_data->next_ptr = NULL;
            }
            // I'm before the first and only node and thefore I become the new first
            else
            {
                iter->previous_ptr = new_data;
                new_data->next_ptr = iter;
                first_ptr = iter;
            }
        }
        // 2+ element list
        else
        {
            // this is never null the first time because empty list case is take care of above
            while(iter != NULL)
            {
                // Should I be inserted before the current node?
                if(strcmp(iter->data, new_data->data) >= 0)
                {
                    // first node case
                    if(iter->previous_ptr == NULL)
                    {
                        new_data->previous_ptr = NULL;
                        new_data->next_ptr = iter;
                        iter->previous_ptr = new_data;
                        first_ptr = new_data;
                    }
                    // intermediate node case
                    else if(iter->next_ptr != NULL)
                    {
                        iter->previous_ptr->next_ptr = new_data;
                        new_data->previous_ptr = iter->previous_ptr;
                        new_data->next_ptr = iter;
                        iter->previous_ptr = new_data;
                    }
                    // last node case
                    else
                    {
                        iter->next_ptr = new_data;
                        new_data->previous_ptr = iter;
                        new_data->next_ptr = NULL;
                    }
                    break;
                }
                // Move to next node
                iter = iter->next_ptr;
            }
        }
    }
    // Print the list
    std::cout << "List: " << std::endl;
    sublink* printer = first_ptr;
    while(printer != NULL)
    {
        std::cout << 't' << printer->data << std::endl;
        printer = printer->next_ptr;
    }
    std::cout << std::endl;
}
int main(int argc, char* argv[])
{
    doubled d;
    char item[30] = "bla bla bla";
    char item2[30] = "meh";
    char item3[30] = "ahhhhhhhh";
    char item4[30] = "dayummmmm";
    d.add_item(item);
    d.add_item(item2);
    d.add_item(item3);
    d.add_item(item4);
    std::cin.get();
    return 0;
}

你可以在这里看到结果:http://ideone.com/EAzsPZ