2014-06-27 44 views
0

我正在研究此程序,該程序讀取文本文件並從文本文件中抓取數據並將其插入到鏈接列表的節點中。刪除單向鏈接列表中特定數字範圍之外的節點

我有整個程序運行,除了節點刪除工作正常。我正在過濾來自文本文件的數據,因此我只需要打印出具有特定範圍內值的數據。我可以用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; 
     } 

回答

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; 
    } 
} 
+0

我其實是有它作爲「或」,但改變了它到'和'出於絕望(我正在嘗試所有的東西......),並忘記在發佈之前將它改回來,但正如你所說的那樣,打印所有東西但不打印任何東西。 – DomBavetta

+0

也許在while循環中,打印出正在被刪除的節點,然後打印出這些節點的淨工資。這會讓你更好地看看循環中發生了什麼。 –

+0

那麼問題就在於每個節點都被刪除了,所以沒有什麼可以打印出來的。 – DomBavetta

0

你應該改變的條件的同時,作爲一個開始。 '& &'應該是'||'因爲它沒有意義的,有「< 45000」,而在同一時間比60000也更大,作爲替代,爲什麼不跳過添加節點列表完全如果不符合這些條件呢?換句話說,在創建列表時,請檢查這些條件,如果不滿足,請不要添加到列表中。這樣你就不會創建一個列表,然後立即返回並修改它。

編輯:

好吧,這個問題,我相信,是用「國際熱核實驗堆while循環。只要你的迭代器條件匹配while循環,你什麼也不做後向前迭代器(因爲你沒有得到回給for循環),因此刪除while循環中的列表的其餘部分。嘗試改變一個'如果',看看你得到什麼。

+0

因爲用於該條件的值在添加到列表後被修改。一個節點可能有45,000的工資,但在扣除0.08計算後,它將是44,160,使其在條件下低於45,000大關。在使用netSalary()函數進行計算之前,我需要先將所有數據添加到列表中。 – DomBavetta

+0

它給我一個錯誤,這個語句「delete nodeToDelete;」它說指針被釋放沒有被分配 – DomBavetta

+0

因爲你正在使用指針,所以首先嚐試'delete&nodeToDelete'。如果這不起作用,請嘗試添加'EmployeePtr nodeToDelete =新員工;'然後使用'nodeToDelete = temp;'你在這裏碰到的是'iter'和'temp'只是指針,並沒有被分配,因此你試圖釋放指針而不是釋放它們指向的內存。 – blh83

0

我想你想的條件是

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

我說認爲因爲我沒有看到你真正想篩選出什麼聲明。

0

最新的解決方案應該注意的主要問題(刪除整個列表,因爲循環開始的頭,而不是ITER),但你可能仍然會碰到的另一個問題。如果最後一個元素被刪除,下一次循環條件被選中,netSalary將被調用一個空指針(因爲iter在它被提前到iter-> link時將爲空)。此外,嘗試修改該循環以解釋空指針可能會導致外部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; 
    } 
}