C++中如何将多类对象数组转为对象链表及相关操作?
C++对象链表问题解答
1. 如何将多类对象数组转换为对象链表?
首先为每个类定义链表节点结构,节点包含类对象和指向下一个节点的指针。之后遍历数组,逐个将数组元素转为链表节点,拼接成完整链表。
示例代码:
#include <iostream> #include <fstream> #include <string> #include <limits> using namespace std; // 修正类名统一(原代码中类名Students和main里的Student不一致) class Student { public: string name; int age; int stuID; }; class Marks { public: int stuID; float test1Mark; float test2Mark; float finalExamMark; }; // Student链表节点 struct StudentNode { Student data; StudentNode* next; // 构造函数简化节点初始化 StudentNode(const Student& s) : data(s), next(nullptr) {} }; // Marks链表节点 struct MarksNode { Marks data; MarksNode* next; MarksNode(const Marks& m) : data(m), next(nullptr) {} }; // 将Student数组转为链表,返回链表头节点 StudentNode* arrayToStudentList(Student* arr, int size) { StudentNode* head = nullptr; StudentNode* tail = nullptr; for (int i = 0; i < size; ++i) { StudentNode* newNode = new StudentNode(arr[i]); if (!head) { // 空链表,第一个节点作为头 head = newNode; tail = newNode; } else { // 追加到链表末尾 tail->next = newNode; tail = newNode; } } return head; } // Marks数组转链表同理 MarksNode* arrayToMarksList(Marks* arr, int size) { MarksNode* head = nullptr; MarksNode* tail = nullptr; for (int i = 0; i < size; ++i) { MarksNode* newNode = new MarksNode(arr[i]); if (!head) { head = newNode; tail = newNode; } else { tail->next = newNode; tail = newNode; } } return head; }
2. 如何将链表传入函数?
根据函数是否需要修改链表结构,分两种传参方式:
- 只读操作(如遍历、打印):直接传入链表头节点的指针即可,函数内仅访问节点数据,不修改链表结构。
- 修改操作(如添加、删除节点):需要传入头节点指针的引用,否则函数内修改的只是指针副本,无法影响原链表。
示例代码:
// 只读:遍历打印Student链表 void printStudentList(StudentNode* head) { StudentNode* current = head; while (current != nullptr) { cout << "姓名:" << current->data.name << " 年龄:" << current->data.age << " 学号:" << current->data.stuID << endl; current = current->next; } } // 修改:向Student链表末尾添加节点(传指针引用) void addStudentNode(StudentNode*& head, const Student& s) { StudentNode* newNode = new StudentNode(s); if (!head) { // 空链表,直接作为头节点 head = newNode; return; } // 找到链表末尾 StudentNode* current = head; while (current->next != nullptr) { current = current->next; } current->next = newNode; }
3. 如何从文本文件向链表添加数据?
无需先填充数组,可直接读取文件内容,每读取一组数据就创建一个链表节点,追加到链表中。核心逻辑是循环读取文件直到结束,每次读取后调用添加节点的函数。
示例代码:
// 从文件读取Student数据并构建链表 StudentNode* populateStudentListFromFile(const string& filename) { ifstream stuFile(filename); if (!stuFile.is_open()) { cerr << "无法打开文件:" << filename << endl; return nullptr; } // 忽略第一行表头(如果文件有表头的话) stuFile.ignore(numeric_limits<streamsize>::max(), '\n'); StudentNode* head = nullptr; Student tempStu; // 循环读取数据,直到文件末尾 while (stuFile >> tempStu.name >> tempStu.age >> tempStu.stuID) { addStudentNode(head, tempStu); } stuFile.close(); return head; } // 从文件读取Marks数据并构建链表 MarksNode* populateMarksListFromFile(const string& filename) { ifstream marksFile(filename); if (!marksFile.is_open()) { cerr << "无法打开文件:" << filename << endl; return nullptr; } marksFile.ignore(numeric_limits<streamsize>::max(), '\n'); MarksNode* head = nullptr; Marks tempMarks; while (marksFile >> tempMarks.stuID >> tempMarks.test1Mark >> tempMarks.test2Mark >> tempMarks.finalExamMark) { MarksNode* newNode = new MarksNode(tempMarks); if (!head) { head = newNode; } else { MarksNode* current = head; while (current->next != nullptr) { current = current->next; } current->next = newNode; } } marksFile.close(); return head; }
主函数调用示例:
int main() { // 直接从文件构建链表 StudentNode* stuList = populateStudentListFromFile("student.txt"); MarksNode* marksList = populateMarksListFromFile("marks.txt"); // 打印链表验证 printStudentList(stuList); // 注意:使用完链表后要手动释放内存,避免内存泄漏 // 此处省略内存释放代码,可自行实现遍历删除每个节点的函数 return 0; }
内容的提问来源于stack exchange,提问作者Averal Verma
相关产品推荐
相关产品推荐

