LinkList C ++删除节点

时间:2016-10-07 10:32:15

标签: c++

删除中间的节点时遇到问题。如果我在中间放置一个位置所有前一个节点都将消失,任何人都可以帮助我,谢谢!

如果我删除前面的部分没有任何问题,但在中间部分会有一些问题。

我现在被困住了。

 #include<iostream>
 #include<string>
 #include <limits>
using namespace std;
struct Student{
    string name;
    int matricNo;
    string course;
    double cgpa;
    Student* link;
};

int main(){
    Student *head = NULL, *last, *newStudent, *target;
    int menu = 0;
    int select;
    while(menu != 6){
    cout << "Student Database.\n";
    cout << "1.Add a student.\n";
    cout << "2.Delete a student.\n";
    cout << "3.View a student's information.\n";
    cout << "4.View all students' information.\n";
    cout << "5.View all students' information with CGPA of 3.0 or higher.\n";
    cout << "6.End program.\n";
    while(!(cin >> menu)){
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "Invalid input.\n";
    }
    if(menu == 1){
    newStudent = new Student;

    if(head == NULL)
        head = newStudent;

        cin.clear();
        cin.ignore(2000,'\n');
        cout << "Please enter the student's name : ";
        getline(cin, newStudent -> name);
        cin.clear();
        cout << "Please enter the Matric Number     : ";
            while(!(cin >> newStudent -> matricNo)){
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid input. Please enter a number.\n";
        }   
        cin.clear();
        cin.ignore(2000,'\n');
        cout << "Please enter the Course    : ";
        getline(cin, newStudent -> course);
        cin.clear();
        cout << "Please enter the student's CGPA : ";
            while(!(cin >> newStudent -> cgpa) || newStudent -> cgpa > 4 || newStudent -> cgpa < 0){
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            cout << "Invalid input. Please enter a value between 0.00 and 4.00\n";
        }
        newStudent -> link = NULL;

    if(last != NULL)
        last -> link = newStudent; 

    last = newStudent;
    system("cls");
    }

    if(menu == 2){
        if(head != NULL){
        cout << "Please enter the matric number of a student : ";
        while(!(cin >> select)){
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "Invalid input.\n";
        }
            for(Student* p = head; p != NULL; p = p -> link){
                if(p -> matricNo == select){
                    target = p;
                    if(head != NULL)
                    head = p -> link;
                    target -> link = NULL;
                    delete target;  
                }
            }
        }
        else if(head == last){
            head -> link=NULL;
            last -> link=NULL;
        }
        else
            cout << "No students in the database.\n";
    }
    if(menu == 3){

        if(head != NULL){
        cout << "Please enter the matric number of a student : ";
        while(!(cin >> select)){
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        cout << "Invalid input.\n";
        }
            for(Student* p = head; p != NULL; p = p -> link){
                if(p -> matricNo == select){
                cout << "Student's Name  : " << p -> name << endl;
                cout << "Matric Number  : " << p -> matricNo << endl;
                cout << "Course         : " << p -> course << endl;
                cout << "CGPA       : " << p -> cgpa << endl;
                cout << "==================================\n";
                }
            }
         }
        else
            cout << "No students in the database.\n";
    }
    if(menu == 4){
        if(head != NULL){
            for(Student* p = head; p != NULL; p = p -> link){
            cout << "Student's Name  : " << p -> name << endl;
            cout << "Matric Number  : " << p -> matricNo << endl;
            cout << "Course         : " << p -> course << endl;
            cout << "CGPA       : " << p -> cgpa << endl;
            cout << "==================================\n";
            }
        }
        else
            cout << "No students in the database.\n";
    }
    if(menu == 5){
        if(head != NULL){
            for(Student* p = head; p != NULL; p = p -> link){
                if(p -> cgpa >=3){
                cout << "Student's Name  : " << p -> name << endl;
                cout << "Matric Number  : " << p -> matricNo << endl;
                cout << "Course         : " << p -> course << endl;
                cout << "CGPA       : " << p -> cgpa << endl;
                cout << "==================================\n";
                }
            }
        }
        else
            cout << "No students in the database.\n";       
    }
    if(menu == 6)
        return 0;
    }   
    system("PAUSE");
    return 0;
}

2 个答案:

答案 0 :(得分:1)

要删除单链接列表中间的节点,首先需要在之前找到要删除的节点。那是因为您需要将其链接设置为(将要删除的)节点链接。

有点图形化,让我们说你的列表看起来像这样:

        +--------+     +--------+     +--------+
... --> | Node A | --> | Node B | --> | Node C | --> ...
        +--------+     +--------+     +--------+

现在假设您要删除“Node B”。要做到这一点,你必须使列表看起来像这样:

                    /---------------\
        +--------+  |   +--------+  |   +--------+
... --> | Node A | -/   | Node B | -+-> | Node C | --> ...
        +--------+      +--------+      +--------+

现在“节点A”没有链接到“节点B”,因此“节点B”实际上不再在列表中。 “节点A”和“节点B”都链接到“节点C”无关紧要,因为您无法访问“节点B”,也因为下一步是删除“节点B”的结构

请注意,当您要删除的节点是列表中的第一个节点时,会出现一种特殊情况。如果找不到列表中的节点,您还应该能够处理。

当然还有其他解决方案(如UKMonkey所述),例如使用标准std::list(或单链接std::forward_list)。所以我认为这只是为了练习链接列表的基本工作原理。

您还可以拥有一个双链表,其中每个节点不仅具有列表中下一个节点的链接,还具有前一个节点的链接。上面概述的原则是相同的。

答案 1 :(得分:0)

当涉及遍历单链表以查找和删除列表中的某个现有节点时,简单的范例转换大大简化了任务。

问题的范式转换是使用指向列表中每个节点的指针,而不是指向列表中每个节点的指针。当你这样做时,if语句的典型笨拙森林会立即消失,并被一个非常简单,直接的算法取代:

for (Student **p=&head; *p; p=&(*p)->next)
{
    if ((*p)->matricNo == select)
    {
        Student *node= *p;
        *p=node->next;
        delete node;
        break;
    }
}