C++ 删除单链表中特定数值范围之外的节点

C++ 删除单链表中特定数值范围之外的节点,c++,linked-list,range,nodes,delete-operator,C++,Linked List,Range,Nodes,Delete Operator,我正在编写一个程序,它读取一个文本文件,从文本文件中提取数据,并将其插入链表的节点中 我有整个程序运行和工作良好,除了节点删除。我正在过滤文本文件中的数据,所以我只需要打印出值在一定范围内的数据。我可以用if()语句实现这一点,它工作得很好,但这不是我想要的结果 我想删除指定范围之外的节点,并释放它们正在使用的内存。我写了几行代码,试图做到这一点,但最终删除了整个列表。所以,如果有人能给我指出正确的方向,告诉我我做错了什么,那就太好了 #include <fstream> #incl

我正在编写一个程序,它读取一个文本文件,从文本文件中提取数据,并将其插入链表的节点中

我有整个程序运行和工作良好,除了节点删除。我正在过滤文本文件中的数据,所以我只需要打印出值在一定范围内的数据。我可以用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;
}
#包括
#包括
使用名称空间std;
结构雇员
{
先串;
字符串lastN;
浮动工资;
浮动奖金;
浮动扣除;
员工链接;
};
typedef Employee*EmployPtr;
void insertatead(EmployPtr&,string,string,float,float,float);
无效插入(EmployPtr&,string,string,float,float,float);
浮动netSalary(EmployPtr&);
int main()
{
//打开文件
fstream-in(“payroll.txt”,ios::in);
//读台词
先串,后串;
浮动工资、奖金、扣减;
EmployPtr head=新员工;
//将所有数据插入链表中的新节点,每次执行循环时都创建一个新节点。
同时(在>>第一次>>最后一次>>工资>>奖金>>扣减中)
插入项(头、头、尾、工资、奖金、扣减);
//关闭文件
in.close();
cout-link;
删除节点删除;
}
cout firstN lastN=lastValue;
临时工资->工资=工资价值;
tempPtr->bonus=bonusValue;
tempPtr->Decredition=DecreditionValue;
temptr->link=afterNode->link;
afterNode->link=temptr;
}
//此函数根据输入节点的薪资、奖金和扣减变量计算净薪资。
float netSalary(EmployPtr&node)
{
浮动净值、新扣减额;
新扣减=((节点->工资)+(节点->奖金))*(节点->扣减);
netSalary=(节点->薪资+节点->奖金)-新扣减;
返回netSalary;
}
编辑:已更改并返回到| |仍有问题

编辑#2:解决方案

while(netSalary(iter)<45000 || netSalary(iter)>60000)
        {
            EmployPtr nodeToDelete = new Employee;
            nodeToDelete = iter;
            iter = iter->link;
            delete nodeToDelete;
        }
while(netSalary(iter)60000)
{
EmployPtr nodeToDelete=新员工;
nodeToDelete=iter;
国际热核实验堆=国际热核实验堆->链接;
删除节点删除;
}
这一行就在这里:

while(netSalary(iter)<45000 && netSalary(iter)>60000)
while(netSalary(iter)60000)
我相信你的条件应该是或(| |)。一个值同时小于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;
    } 
}
for(iter=head;iter!=NULL;iter=iter->link)
{
cout salary;//这样您就可以看到它正在查看的节点
if(国际热核实验堆(iter)<45000 | |国际热核实验堆(iter)>60000)
{
EmployPtr nodeToDelete=iter;
iter=iter->link;//这里的区别在于,您明确地将iter向前推进
删除节点删除;
} 
}

首先,您应该更改while条件。“&&”应该是“| |”,因为“<45000”同时大于60000是没有意义的。另外,如果节点不满足这些条件,为什么不完全跳过向列表中添加节点呢?换句话说,在创建列表时,检查这些条件,如果不满足这些条件,则不要添加到列表中。这样,您就不会创建一个列表,然后立即返回并修改它

编辑:


好吧,我相信问题在于while循环使用了“iter”。只要迭代器与while循环中的条件匹配,您就不必在之后向前移动迭代器(因为您不会返回for循环),从而删除while循环中列表的其余部分。试着把while改为if,看看你得到了什么

我想你希望这个条件

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

while(netSalary(iter)>=45000&&netSalary(iter)最新的解决方案应该解决主要问题(删除整个列表,因为循环以head而不是iter开始),但您可能仍会遇到另一个问题。如果删除最后一个元素,下次检查循环条件时,将在空指针上调用netSalary(因为一旦iter升级到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;
    }
}
EmployPtr iter=水头、温度;
while(iter!=NULL)
{
if(netSalary(iter)60000)
{
//坏节点,删除并前进
EmployPtr nodeToDelete=iter;
国际热核实验堆=国际热核实验堆->链接;
删除节点删除;
} 
其他的
{
//好的节点,写和前进

我可以先把它改成“或”,但出于绝望,我把它改成了“和”(我尝试了一切…)在发布之前忘了更改它,但正如你所说的那样,打印了所有内容,但没有打印任何内容。也许在while循环中,打印出要删除的节点,然后还打印出这些节点的净工资。这会让你更好地了解循环中发生的事情。问题是这样的正在删除y节点,因此没有可打印的内容。请在删除节点之前在while循环中打印该节点。此行:
while(netSalary(iter)60000){cout-link;delete-nodeToDelete;}
因为用于条件的值