【问题标题】:Deleting nodes that are outside of a specific numeric range in a singly linked list删除单链表中特定数值范围之外的节点
【发布时间】:2014-08-18 21:21:53
【问题描述】:

我正在开发这个程序,它读取文本文件并从文本文件中抓取数据并将其插入到链表的节点中。

除了删除节点外,我的整个程序都运行良好。我正在从文本文件中过滤数据,所以我只需要打印出具有特定范围内的值的数据。我可以用 if() 语句来做到这一点,它工作得很好,但这不是我想要的结果。

我想删除指定范围之外的节点并释放它们正在使用的内存。我写了几行代码试图做到这一点,但它最终会删除整个列表。因此,如果有人能指出我正确的方向并告诉我我做错了什么,那就太好了!

#include <fstream>
#include <iostream>
using namespace std;

struct Employee
{
    string firstN;
    string lastN;
    float salary;
    float bonus;
    float deduction;

    Employee *link;
};

typedef Employee* EmployPtr;
void insertAtHead( EmployPtr&, string, string, float, float,float );
void insert( EmployPtr&, string, string, float, float,float );
float netSalary( EmployPtr& );

int main()
{
//Open file
fstream in( "payroll.txt", ios::in );

//Read lines
string first, last;
float salary, bonus, deduction;
EmployPtr head = new Employee;

//Inserts all the data into a new node in the linked list, creating a new node each time the loop executes.
while( in >> first >> last >> salary >> bonus >> deduction)
    insertAtHead (head, first, last, salary, bonus, deduction);

//Close file
in.close();

cout << "-Salary in the range of ($45,000 - $60,000)-\n" << "Printed in format: First Name, Last Name, Salary, Bonus, Deduction, Net Salary.\n";

EmployPtr iter, temp;
for(iter = head; iter!= NULL; iter = iter->link)
{
    temp = head;
    //Deletes nodes outside of range.
    while(netSalary(iter)<45000 || netSalary(iter)>60000)
    {
        EmployPtr nodeToDelete = temp;
        temp = temp->link;
        delete nodeToDelete;
    }

    cout << iter->firstN << ", " << iter->lastN << ", " << iter->salary << ", " << iter->bonus << ", " << iter->deduction << ", " << netSalary(iter) <<endl;

}
    return 0;
}

    //Based off of the input values, this function will create a new node and insert it at the beginning of the linked list. This function ONLY allows insertion at the beginning of the list and no where else.
 void insertAtHead(EmployPtr& head, string firstValue, string lastValue,
            float salaryValue, float bonusValue,float deductionValue)
{
    EmployPtr tempPtr= new Employee;

    tempPtr->firstN = firstValue;
    tempPtr->lastN = lastValue;
    tempPtr->salary = salaryValue;
    tempPtr->bonus = bonusValue;
    tempPtr->deduction = deductionValue;

    tempPtr->link = head;
    head = tempPtr;
}

//Based off of the input values, this function creates a new node and inserts it AFTER the node provided in the argument.
void insert(EmployPtr& afterNode, string firstValue, string lastValue,
        float salaryValue, float bonusValue,float deductionValue)
{
    EmployPtr tempPtr= new Employee;


    tempPtr->firstN = firstValue;
    tempPtr->lastN = lastValue;
    tempPtr->salary = salaryValue;
    tempPtr->bonus = bonusValue;
    tempPtr->deduction = deductionValue;

    tempPtr->link = afterNode->link;
    afterNode->link = tempPtr;
}

//This function calculates a net salary based off of the salary, bonus, and deduction variables of the input node.
float netSalary(EmployPtr& node)
{
    float netSalary, newDeduction;

    newDeduction = ((node->salary) + (node->bonus)) * (node->deduction);
    netSalary = (node->salary + node->bonus) - newDeduction;

    return netSalary;
}

编辑:将 && 改回 ||还是有问题。

编辑 #2:解决方案

while(netSalary(iter)<45000 || netSalary(iter)>60000)
        {
            EmployPtr nodeToDelete = new Employee;
            nodeToDelete = iter;
            iter = iter->link;
            delete nodeToDelete;
        }

【问题讨论】:

    标签: c++ linked-list range nodes delete-operator


    【解决方案1】:

    这一行就在这里:

    while(netSalary(iter)<45000 && netSalary(iter)>60000)
    

    我相信您的条件应该是 OR (||)。一个值同时小于 45000 和大于 60000 是没有意义的。

    给定值 25000,它将小于 45000,但不大于 60000,因此不会删除任何内容。

    编辑: 或许可以尝试以下方式:

    for (iter = head; iter != NULL; iter = iter->link) 
    {
        cout << iter->salary; // so you can see what node it's looking at
        if (netSalary(iter) < 45000 || netSalary(iter) > 60000)
        {
            EmployPtr nodeToDelete = iter;
            iter = iter->link; // difference here is that you're explicitly moving the iter forward
            delete nodeToDelete;
        } 
    }
    

    【讨论】:

    • 我实际上将它作为“或”但出于绝望将其更改为“和”(我正在尝试一切......)并忘记在发布之前将其更改回来但正如您所说并打印所有内容但或不打印任何内容。
    • 也许在while循环中,打印出被删除的节点是什么,然后也打印出这些节点的净薪水是多少。这将使您更好地了解循环中发生的事情。
    • 嗯,问题是每个节点都被删除了,所以没有什么可以打印出来的。
    • 在删除节点之前在while循环中打印。此行:while(netSalary(iter)&lt;45000 &amp;&amp; netSalary(iter)&gt;60000) { cout &lt;&lt; (whatever you want to cout here); EmployPtr nodeToDelete = temp; temp = temp-&gt;link; delete nodeToDelete; }
    【解决方案2】:

    我想你想要的条件是

    while(netSalary(iter) >= 45000  &&  netSalary(iter) <= 60000)
    

    我说想想是因为我没有看到你真正想要过滤掉的东西的声明。

    【讨论】:

      【解决方案3】:

      您应该更改 while 条件,作为开始。 '&&' 应该是 '||'因为 '

      编辑:

      好的,我相信问题在于使用“iter”的 while 循环。一旦迭代器在 while 循环中与您的条件匹配,您就不会在此之后将迭代器向前移动(因为您不会返回到 for 循环),因此会删除 while 循环内的列表的其余部分。尝试将时间更改为“如果”,看看你会得到什么。

      【讨论】:

      • 因为用于条件的值在添加到列表后正在被修改。一个节点可能有 45,000 的薪水,但在扣除 0.08 之后,它将是 44,160,使其低于条件中的 45,000 标记。在使用 netSalary() 函数进行计算之前,我需要先将所有数据添加到列表中。
      • 它给了我这个语句“delete nodeToDelete;”的错误它说被释放的指针没有被分配
      • 首先尝试'delete &nodeToDelete',因为您正在使用指针。如果这不起作用,请尝试添加 'EmployeePtr nodeToDelete = new Employee;'然后使用'nodeToDelete = temp;'你在这里遇到的是'iter'和'temp'只是指针并且没有被分配,因此你试图释放指针而不是释放它们指向的内存。
      【解决方案4】:

      最新的解决方案应该解决主要问题(删除整个列表,因为循环以 head 而不是 iter 开始),但您可能仍会遇到另一个问题。如果最后一个元素被删除,下次检查循环条件时,netSalary 将在一个空指针上调用(因为一旦它前进到 iter->link,iter 就会为空)。此外,尝试修改该循环以考虑空指针可能会导致外部 for 循环尝试访问空指针的链接成员。

      我可以建议的最简单的解决方案是修改代码以仅使用一个 while 循环和条件,如下面的代码所示:

      EmployPtr iter = head, temp;
      while(iter!= NULL)
      {
          if(netSalary(iter)<45000 || netSalary(iter)>60000)
          {
              // bad node, delete and advance
              EmployPtr nodeToDelete = iter; 
              iter = iter->link;
              delete nodeToDelete;
          } 
          else 
          {
              // good node, write and advance
              cout << iter->firstN << ", " << iter->lastN << ", " << iter->salary << ", " << iter->bonus << ", " << iter->deduction << ", " << netSalary(iter) <<endl;
              iter = iter->link;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2019-02-23
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-26
        • 2020-02-11
        相关资源
        最近更新 更多