删除单个链接列表中特定数值范围之外的节点

时间:2014-06-27 17:10:38

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

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

除了删除节点之外,我还运行整个程序并正常工作。我正在过滤文本文件中的数据,所以我只需要打印出具有一定范围内值的数据。我可以使用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;
}

编辑:改变&amp;&amp;回到||还有问题。

编辑#2:解决方案

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

4 个答案:

答案 0 :(得分: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;
    } 
}

答案 1 :(得分:0)

您应该更改while条件,作为开始。 '&amp;&amp;'应该是'||'因为没有'&lt; 45000'同时大于60000.另外,作为替代方案,如果不满足这些条件,为什么不跳过将节点完全添加到列表中?换句话说,在创建列表时,请检查这些条件,如果不满足则不要添加到列表中。这样你就不会创建一个列表,然后立即返回并修改它。

编辑:

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

答案 2 :(得分:0)

我认为你希望条件是

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

我说因为我没有看到你真正想要过滤的内容的陈述。

答案 3 :(得分:0)

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

我可以建议的最简单的解决方案是修改代码,只使用一个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;
    }
}