链接列表仅在添加新节点后打印最后一个元素

时间:2015-03-30 00:51:49

标签: c++

我是C ++的新手,想知道为什么我的程序在添加新节点后只打印输入文件的最后一个节点。添加新节点后,它仅打印最后一个节点和用户输入的节点。

我还需要帮助搜索所有学生的最高gpa,并显示哪个学生和他们的gpa一样。

这是输入文件:

14
Breen_Jeremy
482929
3.5
Burgess_Patrick
492929
3.2
Catalan_Kristian
393923
2.5
Clark_Brenna
848292
4.0
Duda_Heather
292032
3.7
Freeland_Jesse
391939
4.0
Jarvis_Stephen
392939
2.5
Lemieux_Tyler
392934
3.5
OConnell_Kelly
103939
4.0
Osborne_John
193945
2.8
Richards_Daniel
494585
3.0
Swanbeck_James
693922
3.5
Tayek_Chandler
592022
3.0
Whippen_Andrew
199502
2.8

这是我的计划:

 // This program does some basic functionalities of using a linked list

 #include<iostream>
 #include<string.h>
 #include<cstring>
 #include<fstream>
 using namespace std;

struct node
{
string name;
int student_ID;
 double gpa;
node * next;
};



int main()
{
// Variable definitions
node * first;               // Pointer to the first node in the list
node * last;                // Pointer to the last node in the list
char more_nodes = 'y';  // Control to know if the user wants to enter more
int numStudents;
double largest_GPA;
string best_student;
bool swap = true;
ifstream database;
void print(node * first);

database.open("class_list.txt");


database >> numStudents;

// Creates the first node
first = new node;           // Create the first node
first -> next = NULL;   // Point it to NULL (since it's the end)
last = first;               // Point last to it (since it's the end)

 for (int i = 0; i < numStudents; i++)      
  {

  database >> first -> name;
  database >> first -> student_ID;
  database >> first -> gpa; 
  print(first);
  }//end for




// This loop adds one new node, loads data into it, and updates pointers   
  while (more_nodes == 'y')
   {
   last -> next = new node;         // Get a new node tacked onto the end of the list

cout << "Enter the name of the student" << endl;
cin >> last -> next -> name;
cout << "Enter the student ID" << endl;
cin >> last -> next -> student_ID;
cout << "Enter the GPA of the student" << endl;
cin >> last -> next -> gpa;
last -> next -> next = NULL;        // Point the new node to NULL
last = last -> next;        // Toggle last to point to this new node (since it's the new "last")


cout << "Do you have more students to enter? Enter y for yes or n for no" << endl;
cin >> more_nodes;

++numStudents;
print(first);
}//end while


node * temp;
temp = first;


while (temp -> next != NULL)
{
while(swap)
{
   swap = false;
      if (temp -> next -> gpa > temp-> gpa)
       {
        largest_GPA = temp -> gpa;
         temp -> gpa = temp -> next -> gpa;
         temp -> next -> gpa = largest_GPA;
         temp -> name = best_student;
         swap = true;
         }//end if
  }//end while
  temp = temp -> next;
 }//end while

 cout << "The best student is " << best_student <<endl;
 cout << "The largest GPA is " << largest_GPA <<endl;


  database.close();

  return 0;

 }//end main



 // Print out the linked list by having a temporary pointer scroll through the entire list

void print(node * first)
  {
    node * temp;                // Make a temporary (dummy) pointer
    temp = first;               // Point it to the first node in the list

    while(temp != NULL)     // Continue until temp reaches NULL (the end)
    {


    cout << temp -> name << endl;       
    cout << temp -> student_ID << endl;
    cout << temp -> gpa << endl;
    temp = temp -> next;                    // Move temp to the next node

      }//end while

   }//end function

2 个答案:

答案 0 :(得分:1)

首先,std::string定义的正确标头是:

#include <string>

这些以不同的方式引用C字符串库:

#include<string.h> // In the global namespace.
#include<cstring>  // In the std namespace.

如果程序与编译器一起编译,则归因于iostreamfstream标头的实现,不应该依赖它。它没有与我编译。

接下来,来自文件的循环加载记录仅创建并重用一个节点。这是一种纠正错误的方法:

for(int i = 0; i < numStudents; i++)
{
    node* temp = new node;
    database >> temp->name;
    database >> temp->student_ID;
    database >> temp->gpa;
    temp->next = NULL;
    if(first == NULL)
    {
        first = last = temp;
    }
    else
    {
        last->next = temp;
        last = temp;
    }
}//end for

print(first);

最后,要找到最佳GPA,请跟踪GPA最大的节点:

node* temp = first;
node* best = first;
while(temp != NULL)
{
    if(temp->gpa > best->gpa)
    {
        best = temp;
    }
    temp = temp->next;
}//end while

cout << "The best student is " << best->name << endl;
cout << "The largest GPA is " << best->gpa << endl;

要考虑的其他一些事情:

  • 如果文件为空或不存在怎么办?
  • 如果文件中的学生人数为0
  • ,该怎么办?
  • 你如何处理最大GPA的平局?文件中有一个三向关系。

原样的代码不会处理这些条件。

答案 1 :(得分:0)

对我来说代码太长了,但是,新手并使用指针可能会导致头疼。如果您有额外的时间,请先尝试Java。你将更难以搞砸指针(因为你无法访问它们),你仍然可以构建像链表一样的结构。

此外,我不喜欢你的循环结构,你的循环是初始循环(i = 0),然后其余部分(i> = 0),当它可能更容易将它全部放在一个而。我建议这样的事情:

continueprocessing = false;
if( filehascontents ) continueprocessing = true;
while( continueprocessing )
{
    if( !filestillhascontents )
    {
        continueprocessing = false;
        continue;//or break; whatever your style
    }

    /*read contents for this loop*/

    /*validate contents to process are valid node data*/
    if( !valid node data ) continue;

    //if we are still here that means we got data, and its valid node data
    node *n = new node;
    /*also initialize n with the data*/

    //you integrate this into the single loop, to me that's better, up to you
    if( first == null )
    {
        first = n;
        last = n;
        continue;
    }

    //now we are done with the initial linking case, work the regular cases
    last->next = n;
    last = n;
}

基本上我给你看的样式你假设常规情况,但是开始循环检查特殊条件,如果你碰到它们就提前退出。那样你的结构是(循环)(特殊条件块)(常规大小写块)(endloop)

无论如何你的自己的代码,你的for循环,这是我的(一个添加节点),将所有东西设置为第一,并保持覆盖那里的数据,这就是为什么你只有一个节点,因为你从来没有添加节点。

作为一个挑剔,你在中间有一个使用“swap”的循环,但交换定义一直在那里,用实际使用它的代码向下移动初始化,以后更容易使用。

最后你的交换功能是错误的,保持它简单但工作的唯一方法是每次交换时重新初始化temp,所以你再次从头开始搜索,直到你确定整个列表都在顺序。

编辑:我明白了,它不仅是错误的,它有各种各样的错误,不确定你是否想要订购你的清单,或者你只是在寻找最大的节点,所以作为另一个挑剔,试着过分描述你的名字,并试图对语义的挑剔,以便其他人和你以后更容易阅读代码,我会将temp重命名为maxgpastudent,甚至结果,如果你只是寻找最大节点,因为它将是你的结果。

然后不要使用maximumGPA作为交换的临时变量,它是最大的GPA,它应该只包含最大的GPA,如果你需要一个临时变量,创建一个。最后,如果你试图重新排序,重做函数,因为你的任务混合了一切,你交换gpas,但没有交换学生名,你没有交换值,它是一个链表,交换链接。