You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 09:20:27