簡體   English   中英

雙鏈表插入項算法有缺陷

[英]Double-linked-list insert item algorithm flawed

我寫了一個雙鏈表:

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)始終為true,不應為true。

有人看到這個程序有問題嗎?

您可能是忘記了將上一個或下一個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\0";
    char item2[30] = "meh\0";
    char item3[30] = "ahhhhhhhh\0";
    char item4[30] = "dayummmmm\0";
    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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM