如何在c++链表中修改数据

How To Modify Data In a c++ Linked List

本文关键字:修改 数据 链表 c++      更新时间:2023-10-16

我在c++中使用链表的概念制作了一个学生记录系统。该程序将在三种不同的考试中获取学生证、姓名和分数。然后,它将根据这些考试成绩计算总百分比,并根据总百分比显示相关消息。程序正在运行,没有任何错误。

但是我希望student id是唯一的。例如,如果用户输入一个已经分配给前一个学生的学生id,那么它将显示一条消息,"请输入不同的id"。

我该怎么做呢?如有任何帮助,不胜感激。

struct student
{
int id;
char name[MAX];
string status;
double aggr;
int matric_marks, inter_marks, entryTest_marks;
};
struct node
{
struct student *data;
struct node *next;

node()                  
{                       
 data = 0;              
 next = NULL;            
}    
};
struct student *readStudent()
{
clearWindow();
struct student *stdnt = new student;
gotoxy(33,8);cout<<"Student ID: ";
while(!(cin >> stdnt->id) || cin.peek() != 'n')
{
     char ch;
     cin.clear();
     cout << "sorry";
     while(cin.get(ch) && ch != 'n');
}
cin.ignore();
gotoxy(33,10);cout<<"Student Name: ";
cin.getline(stdnt->name, 50);
gotoxy(33,12);cout<<"Enter Matriculation Marks: ";
cin>>(stdnt->matric_marks);

gotoxy(33,14);cout<<"Enter Intermediate Marks: ";
cin>>(stdnt->inter_marks);

gotoxy(33,16);cout<<"Enter Entry Test Marks: ";
cin>>(stdnt->entryTest_marks);
stdnt->aggr = calculate_aggregiate(stdnt);
gotoxy(33,18);cout<<"Student Aggregate Marks: "<< stdnt->aggr;
if (stdnt->aggr >= 70)
{
    gotoxy(33,20);cout<<"Student Registered In Electrical Engg";
}
else if (stdnt->aggr >= 60)
{
    gotoxy(33,22);cout<<"Student Registered In Mechanical Engg";
}
else if (stdnt->aggr >=50)
{
    gotoxy(33,24);cout<<"Student Registered In Computer Science";
}
else
{
    gotoxy(33,20);cout<<"Sorry! The Student Doesnt Qualify";
}
return stdnt;
}

struct node *createDatabase(int size)
{
int i = 0;
struct node *head = NULL;
struct node *last = NULL;

for(i = 0; i < size; i++)
{
    struct student *stdnt = readStudent();

    struct node * current = new node;
    current->data = stdnt;
    current->next = NULL;

    if(last)
        last->next = current;
    else
        head = current;

    last = current;
}
return head;
}

struct node  *InsertRecord(struct node *head)
{
struct  node *record = new node;
struct student *stdnt = readStudent();
record->data=stdnt;
record->next=head;
return record;
}
double calculate_aggregiate(struct student *stud)
{    
student *stdnt = stud;
double aggr;
aggr = stdnt->matric_marks * 10/100  + stdnt->inter_marks * 50/100 + 
    stdnt->entryTest_marks * 40/100;
return aggr;
}
struct node *DeleteRecord(struct node *head)
{
clearWindow();
struct node *curr,*prev, *temp;
int tdata;
if(head==NULL)
{
gotoxy(33,10);cout<<"NO RECORDS TO DELETE......!";
}
else
{
gotoxy(33,10);cout<<"Enter Student ID To Be Deleted: ";
cin>>tdata;
prev=curr=head;
while((curr!=NULL)&&(curr->data->id!=tdata))
{
prev=curr;
curr=curr->next;
}
if(curr==NULL)
{
gotoxy(33,12);cout<<"The Requested ID Is Not Found...!";
}
else if(curr==head)
{
head=head->next;
gotoxy(33,12);cout<<"DATA DELETED....!";
}
else
{
prev->next=curr->next;
if(curr->next==NULL)
{
  temp=prev;
}
gotoxy(33,12);cout<<"DATA DELETED....!"<<tdata;
}
delete(curr);
}    
return head;
}
void ModifyRecord(struct node *head)
{
 clearWindow();
 int ch, sid;
 struct node *current;
 struct student *stdnt;
 if (head==NULL)
 {
     gotoxy(33,8);cout<<"NO RECORD TO MODIFY..!";
 }
 else
 {
     gotoxy(33,8);cout<<"Enter Student ID To Modify: ";
     cin>>sid;
     current=head;
 while((current!=NULL) && (current->data->id!=sid))
 {
 current=current->next;
 }
 if (current==NULL) 
 {
 gotoxy(33,10);cout<<"The Requested ID is Not Found";
 }
 else if(current->data->id==sid)
 {
 gotoxy(33,10);cout<<"What Do You Want To Modify";
 gotoxy(33,12);cout<<"1. Student's Name";
 gotoxy(33,14);cout<<"2. Student's Matric Marks";
 gotoxy(33,16);cout<<"3. Student's Intermediate Marks";
 gotoxy(33,18);cout<<"4. Student's Entry Test Marks";
 gotoxy(33,20);cout<<"Enter Your Choice: ";
 cin>>ch;
 switch(ch)
 {
 case 1 :  gotoxy(33,22);cout<<"Enter New Name: ";
      cin.getline(current->data->name, 50);break;
 case 2 :  gotoxy(33,22);cout<<"Enter New Matric Marks: ";
      cin>>(current->data->matric_marks);break;
 case 3 :  gotoxy(33,22);cout<<"Enter New Intermediate Marks: ";
      cin>>(current->data->inter_marks);break;
 case 4 :  gotoxy(33,22);cout<<"Enter New Entry Test Marks: ";
      cin>>(current->data->entryTest_marks);break;
      current->data->aggr = current->data->matric_marks * 10/100  + current->data-               >inter_marks * 50/100 + 
    current->data->entryTest_marks * 40/100;
 }
 gotoxy(33,24);cout<<"RECORD MODIFIED....!";
 }

 }

 }

void SearchRecord(struct node *head)
{
clearWindow();
int s_id;
 struct node *current;
 if (head==NULL)
 {
     gotoxy(33,8);cout<<"NO RECORD TO SEARCH..!";
 }
 else
 {
     gotoxy(33,8);cout<<"Enter Student ID To Be Searched: ";
     cin>>s_id;
     current=head;
 while ((current!=NULL) && (current->data->id!=s_id))
{
 current=current->next;
}
 if (current==NULL) 
{
gotoxy(33,10);cout<<"The Requested ID is Not Found";
}
else     if (current->data->id==s_id)
    {
         gotoxy(33,10);cout<<"Student ID: "<<current->data->id;
         gotoxy(33,12);cout<<"Student Name: "<<current->data->name;
         gotoxy(33,14);cout<<"Student Matric Marks: "<<current->data->matric_marks;
         gotoxy(33,16);cout<<"Student Intermediate Marks: "<<current->data - >inter_marks;
         gotoxy(33,18);cout<<"Student Entry Test  Marks: "<<current->data- >entryTest_marks;
         gotoxy(33,20);cout<<"Student Aggregate Marks: "<<current->data->aggr;
    if (current->data->aggr >= 70)
{
    gotoxy(33,22);cout<<"Student Registered In Electrical Engg";
}
else if (current->data->aggr >= 60)
{
    gotoxy(33,22);cout<<"Student Registered In Mechanical Engg";
}
else if (current->data->aggr >=50)
{
    gotoxy(33,22);cout<<"Student Registered In Computer Science";
}
else
{
    gotoxy(33,22);cout<<"Sorry! The Student Doesnt Qualify";
}
     }     

 }
 }

void print(struct node *head)
{
clearWindow_p();
struct node *current = head;
if (head == NULL)
{
    gotoxy(33,8);cout<<"No Student Registered Yet......!";
}
else
{
    cout<<"ntttttSTUDENTS STATISTICS";
while(current)
{
    struct student *stdnt = current->data;
    cout<<"nttttt--------------------------------  ";
    cout<<"ntttttStudent ID   :"<<stdnt->id;
    cout<<"ntttttStudent Name   :"<<stdnt->name;
    cout<<"ntttttMatric Marks :"<<stdnt->matric_marks;
    cout<<"ntttttIntermediate Marks :"<<stdnt->inter_marks;
    cout<<"ntttttEntry Test Marks: "<<stdnt->entryTest_marks;
    cout<<"ntttttAggregate: "<<stdnt->aggr;
    if (stdnt->aggr >= 70)
{
    cout<<"ntttttStudent Registered In Electrical Engg";
}
else if (stdnt->aggr >= 60)
{
    cout<<"ntttttStudent Registered In Mechanical Engg";
}
else if (stdnt->aggr >=50)
{
    cout<<"ntttttStudent Registered In Computer Science";
}
else
{
    cout<<"ntttttSorry! The Student Doesnt Qualify";
}

    current=current->next;
}
    cout<<"nttttt--------------------------------";

}
}


int compareStudents(struct student *left, struct student *right)
{
    return strcmp(left->name, right->name);
}


struct node *sort(struct node *head)
{

    //using bubble sort

    int swapped = 0;

    do
    {    
        swapped = 0;
        struct node *current = head;
        struct node *previous = NULL;

        while(current && current->next)
        {
            if(compareStudents(current->data, current->next->data) > 0)
            {
                //swap here
                struct node *next = current->next;
                if(previous)
                {
                    previous->next = next;        
                }
                else
                {
                    head = next;
                }

                current->next = next->next;
                previous = next;
                previous->next = current;    
                swapped = 1;
            }
            else
            {
                previous = current;
                current = current->next;
            }

        }

    } while(swapped);    

    return head;
}

int main()
{
    system("color f0");
    window();
    SetColor(28);
        int total,i,choice;
        int x = 2;
        struct node *head;
        head=NULL;
        do
        {
            menu:
            gotoxy(x, 8);cout<<"1.Create a Record File";
            gotoxy(x, 10);cout<<"2.Insert Student's Record";
            gotoxy(x, 12);cout<<"3.Modify Student's Record";
            gotoxy(x, 14);cout<<"4.Delete Student's Record";
            gotoxy(x, 16);cout<<"5.Search Student's Record";
            gotoxy(x, 18);cout<<"6.Print All Records";
            gotoxy(x, 20);cout<<"7.Sort According To Names";
            gotoxy(x, 22);cout<<"8.Clear The Screen";
            gotoxy(x, 24);cout<<"9.Exit";
            gotoxy(x, 26);cout<<"Enter your choice";
            cout<<" [ ]bb";
            cin>>choice;
            switch(choice)
            {
                case 1:
                    clearWindow();
                    gotoxy(33, 8);cout<<"How Many Students Do You Want To Register: ";
                    cin>>total;
                    head=createDatabase(total);
                    break;
                case 2:
                    head=InsertRecord(head);
                    break;
                case 3:
                    ModifyRecord(head);
                    break;
                case 4:
                    DeleteRecord(head);
                    break;
                case 5:
                    SearchRecord(head);
                    break;
                case 6:
                    print(head);
                    break;
                case 7:
                    sort(head);
                    print(head);
                    break;
                case 8:
                    main();
                    break;
                default: gotoxy(33,8);cout<<"INVALID OPTION";
        }
        }while(choice!=9);
    getch();
    return 0;
} 

既然使用的是c++,就应该充分利用内置类型。如果只有一个学生具有给定的ID,则使用std::map<>模板。例如:

struct student
{
  char name[MAX];
  string status;
  double aggr;
  int matric_marks, inter_marks, entryTest_marks;
};
map<int, student> students;

then,遍历学生:

for (auto i = students.begin(); i != students.end(); ++i) {
    int studentId = i->first;
    student& student = i->second;
    student.aggr = ...
}

(auto是c++ 11,不是所有的编译器默认启用它。看到这里。)

如果你知道学生id的范围,并且它在一个可行的内存范围内,你可以使用UsedId[]数组

如果范围太大而无法保存,则使用Hashmap,(c++中的MAP)

我可能会实现一个叫做FindRecordByID的东西。

struct student *FindRecordByID(struct node *head, int id) {
    for(; head != NULL; head = head->next)
        if (head->data->id == id)
            return head->data;
    return NULL;
}

然后,当您执行create_new_student例程时,您可以使用它来验证给定的ID是否尚未使用。