排序链表在每次执行时插入重复项

Sorted linked list inserting duplicates at each execution

我有一个函数可以从文件中读取数据,然后根据每一行数据的特定字段以递增顺序插入。

如果我编译并 运行 这部分代码,它最初会排序,但是一旦我重复该操作,我就会得到一个排序的副本,如果我再 运行 一次,每个项目都会出现3次。

如何让这段代码停止插入重复项?

void sortData(Node *& head, Node * data)
{
    ifstream fin("data.txt");
    int acc; string fname, lname; double bal;
    while (fin >> acc >> fname >> lname >> bal)
    {
        data = new Node;
        data->account = acc;
        data->fname = fname;
        data->lname = lname;
        data->balance = bal;
        data->next = NULL;

        if (head == NULL)
        {
            head = data;
        }

        else if (data->balance <= head->balance)
        {
            data->next = head;
            head = data;
        }

        else
        {
            Node * temp1 = head;
            Node * temp2 = temp1->next;

            while (temp2 != NULL && data->balance > temp2 ->balance)
            {
                temp1 = temp2 ;
                temp2 = temp2 ->next;
            }

            data->next = t2;
            temp1 ->next = data;
        }

    }

    Node * temp = head;
    while (temp != NULL)
    {
        cout << temp->account << " " << temp->fname << " " << temp->lname << " " << temp->balance << "\n";
        temp = temp->next;
    }

    fin.close();

}

清晰度。

程序 运行 有一个简单的菜单,所以当我第一次构建和 运行 时,我可以做几件事,插入新记录,删除,显示所有记录(其中问题是),然后退出。我可以尽可能多地重复每个动作,期待退出(显然)。

初始运行,然后按账号显示所有记录:

1111 FName1 LName1 400.56

2222 FName2 LName2 23.45

3333 FName3 LName3 4599.91

4444 FName4 LName4 1000.5

效果很好。

但是

当我想再次显示所有记录时,我看到了这个

1111 FName1 LName1 400.56

1111 FName1 LName1 400.56

2222 FName2 LName2 23.45

2222 FName2 LName2 23.45

3333 FName3 LName3 4599.91

3333 FName3 LName3 4599.91

4444 FName4 LName4 1000.5

4444 FName4 LName4 1000.5

我没有重新插入文件,只是按升序打印数据。

您在一个函数中做的事情太多了。将它们分成更小的、可重用的函数。

// Function to insert the data sorted in an order.
void insertSortedData(Node*& head,
                      int acc,
                      std::string const& fname,
                      std::string const& lname,
                      double bal)
{
   // If the list is empty, create a node and return.
   Node* newNode = new Node(acc, fname, lname, bal)
   if ( head == NULL )
   {
      head = newNode;
      return;
   }

   // If the value of the new node is less or equat to the value
   // of the head node, make it the head node and return.
   if (newNode->balance <= head->balance)
   {
      newNode->next = head;
      head = newNode;
      return;
   }

   // Insert new node at the right place.
   Node * temp1 = head;
   Node * temp2 = temp1->next;

   while (temp2 != NULL && newNode->balance > temp2->balance)
   {
      temp1 = temp2 ;
      temp2 = temp2->next;
   }

   newNode->next = temp2;
   temp1->next = newNode;
}

// Function to read data from a file and create
// a sorted list.
void readDataFromFile(std::string const& file,
                      Node*& head)
{
   std::ifstream fin(file);
   int acc;
   std::string fname;
   std::string lname;
   double bal;
   while (fin >> acc >> fname >> lname >> bal)
   {
      insertSortedData(head, acc, fname, lname, bal);
   }
}

// Functoin to print the contents of a list.
void printList(Node* head)
{
   Node* temp = head;
   while (temp != NULL)
   {
      cout << temp->account << " " << temp->fname << " " << temp->lname << " " << temp->balance << "\n";
      temp = temp->next;
   }
}

然后,您可以分别调用:

int main()
{
   Node* head = NULL;

   // Read data from a file.
   readDataFromFile("data-1.txt", head);

   // Print the data
   printList(head);


   // Read data from a different file.
   readDataFromFile("data-2.txt", head);

   // Print again.
   printList(head);
}

除了你的函数做的太多,甚至没有看到调用代码之外,我可以从你的输出中看出——如果你显示的实际上是唯一的输出——你调用 sortedData多次。每次调用 sortedData 时,sortedData 都会以排序的方式插入输入文件中的所有条目,而不管它们是否已经存在!所以在 n 次调用之后,您的列表中有 n 个数据元素的副本。

想想你想让你的函数做什么。现在你的函数 每次调用 :

while 输入文件中还有更多条目:

  1. 从输入文件中读取下一个条目。
  2. 按排序方式将条目插入列表。

您现在有了输入文件中所有条目的排序列表。您打印列表中的所有条目。

在 return 之后,您传递给函数的列表头仍然指向包含您刚刚读取的所有条目的有效列表。

如果你只想显示所有条目,你唯一需要重复的事情 是打印部分,但是如果您再次调用 sortedData ,您将重复整个函数,这次您传递的列表不是空的,但已经包含输入文件中的每个条目,因此再次添加每个条目in a sorted manner 将为您提供每个条目的副本。所以对你来说最简单的解决方案是在启动时调用你的函数一次,然后只调用一个 printList() 函数,它只执行打印部分:

void printList(Node *head){//local copy of the pointer, can change this
    while (head != NULL)
    {
       cout << head->account << " " << head->fname << " " << 
           head->lname << " " << head->balance << "\n";
       head = head->next;
    }
}