前言:
首先,数据结构这个东西并不针对某一种编程语言,但是很多初学者在学习过c语言后先接触的是有关c语言实现的基础数据结构(例如链表,栈,队列等),后面学会了C++之后反而有些束手束脚,用C++的类去实现链表时反而造成了内存泄漏。
这是因为,我们知道,如果在类内创建对象,那么他在主函数结束后就会自动调用类的析构函数(没写的话会调用默认析构函数),所以有同学就会以为在类中写链式结构时不需要delete或者free,这是错误的想法,因为类的析构只是释放类的内部空间,对于new和malloc所建立的堆区空间仍旧需要调用delete或free。
好的那么废话就不再多说了,我这篇文章已经把源码放到文章末尾了,有需要的直接拿走不谢!当然作者很希望各位看官能给本人点个小赞,谢谢!
Student:学生类
那么首先是学生类,我设计的有姓名学号,性别年龄,科目成绩这五个属性,然后不允许使用拷贝构造函数和移动构造函数以及赋值函数(我想应该也不会有人拿自己复制自己或者在班级里面加上两次自己吧?),构造函数因为属性较多的缘故,显得这行有点长。
class Student {
public:
string name; //学生姓名
string account; //学号
string sex; //性别
int age; //年龄
int grade; //科目成绩
Student* next; //下一节点
Student() {
next = nullptr;
}
Student(Student& s) = delete;
Student(Student&& x) = delete;
Student operator=(Student& x) = delete;
Student operator=(Student&& x) = delete;
Student(string name, string account, string sex, int age, int grade): name(name), account(account), sex(sex), age(age), grade(grade), next(nullptr) { cout << "Creat Student" << endl; }
~Student() { cout << "Delete a Student" << endl; }
void printStudent() const {
cout << "姓名:" << name;
cout << " 学号:" << account;
cout << " 性别:" << sex;
cout << " 年龄:" << age;
cout << " 本科目成绩:" << grade << endl;
}
};
这里的printStudent呢就是打印函数,打印学生信息。
Class:班级类
链表的结构就是用指针直接对每一个学生对象进行链接。
那么可以看到呢,每一个课程肯定有自己单独的任课老师,班级号,课程名这些,当然关于头结点这个部分,我将其设为账号-1的非学生节点(我承认,确实是为了省事)。
然后和学生一样,不允许使用拷贝构造函数和移动构造函数以及赋值函数,在对链表进行增删查改的时候我是以学号作为对比属性进行的,这个相关操作也写在下面的代码中了。
class Class {
private:
string teacher_name; //老师姓名
string class_name; //班级(课程)名
string class_account; //班级(课程)号
Student* student_head; //班长(头结点)
int num; //班级学生人数
public:
Class(string tn, string cn, string ca, string n = "null", string a = "-1", string s = "null", int age = -1, int grade = -1) {
student_head = new Student(n, a, s, age, grade);
teacher_name = tn;
class_name = cn;
class_account = ca;
num = 0;
student_head->next = nullptr;
cout << "Creat Class" << endl;
}
~Class() {
cout << "Delete Class" << endl;
}
Class(Class& x) = delete;
Class(Class&& x) = delete;
Class operator=(Class& x) = delete;
Class operator=(Class&& x) = delete;
Student& checkStudent(string account) { //根据学号获取学生信息
Student* p = student_head;
while (p != nullptr)
{
if (p->account == account) {
cout << "此学生在本班中!" << endl;
return *p;
}
p = p->next;
}
cout << "此学生不在本班!请确认学生信息!" << endl;
return *student_head;
}
bool changeStudent(string account, int t) { //根据学号改变学生成绩
Student* p = student_head;
while (p != nullptr) {
if (p->account == account) {
p->grade = t;
cout << "学生成绩修改完毕" << endl;
return true;
}
p = p->next;
}
cout << "此学生不在本班中!" << endl;
return false;
}
bool addstudent(string n, string a, string s, int age, int grade){//添加学生
Student* p = student_head;
Student* newstudent = new Student(n, a, s, age, grade);
while (p->next != nullptr) {
p = p->next;
}
p->next = newstudent;
num++;
return true;
}
bool deleteStudent(string account) { //删除学生
Student* p = student_head;
Student* temp = nullptr; //记录父节点
while (p != nullptr) {
if (p->account == account) {
if (p == student_head) {
student_head = student_head->next;
delete p;
num--;
return true;
}
temp->next = p->next;
delete p;
num--;
return true;
}
temp = p;
p = p->next;
}
cout << "此学生不在本班中!" << endl;
return false;
}
bool deleteAll() {
Student* p;
while (student_head != nullptr) {
p = student_head;
student_head = student_head->next;
delete p;
}
return true;
}
void printStudent() const { //打印班级学生信息
Student* p = student_head->next;
while (p != nullptr) {
p->printStudent();
p = p->next;
}
}
void printClass() const { //打印课程信息
cout << "老师姓名:" << teacher_name;
cout << " 课程号:" << class_account;
cout << " 课程名:" << class_name;
cout << " 本科目班级人数:" << num << endl;
}
};
总结
那么用类写链表呢,要注意的就是我在开篇时提到的那些,下面是我用于测试的部分(主函数)
main
int main() {
string name[4] = { "牛二", "张三", "李四", "王五" };
string account[4] = { "1234.56", "01", "10", "11" };
string sex[3] = { "男", "男", "男" };
Class a(name[0], "高数", account[0]);
for (int i = 1; i < 4; i++) {
a.addstudent(name[i], account[i], sex[i - 1], 21, 100);
}
if (a.changeStudent(account[1], 59)) {
a.checkStudent(account[2]);
a.printClass();
a.printStudent();
a.deleteStudent(account[2]);
a.printClass();
a.printStudent();
a.checkStudent(account[2]);
}
a.deleteAll();
return 0;
}
运行结果
源代码
#include<iostream>
#include<string>
using namespace std;
class Student {
public:
string name; //学生姓名
string account; //学号
string sex; //性别
int age; //年龄
int grade; //科目成绩
Student* next; //下一节点
Student() {
next = nullptr;
}
Student(Student& s) = delete;
Student(Student&& x) = delete;
Student operator=(Student& x) = delete;
Student operator=(Student&& x) = delete;
Student(string name, string account, string sex, int age, int grade): name(name), account(account), sex(sex), age(age), grade(grade), next(nullptr) { cout << "Creat Student" << endl; }
~Student() { cout << "Delete a Student" << endl; }
void printStudent() const {
cout << "姓名:" << name;
cout << " 学号:" << account;
cout << " 性别:" << sex;
cout << " 年龄:" << age;
cout << " 本科目成绩:" << grade << endl;
}
};
class Class {
private:
string teacher_name; //老师姓名
string class_name; //班级(课程)名
string class_account; //班级(课程)号
Student* student_head; //班长(头结点)
int num; //班级学生人数
public:
Class(string tn, string cn, string ca, string n = "null", string a = "-1", string s = "null", int age = -1, int grade = -1) {
student_head = new Student(n, a, s, age, grade);
teacher_name = tn;
class_name = cn;
class_account = ca;
num = 0;
student_head->next = nullptr;
cout << "Creat Class" << endl;
}
~Class() {
cout << "Delete Class" << endl;
}
Class(Class& x) = delete;
Class(Class&& x) = delete;
Class operator=(Class& x) = delete;
Class operator=(Class&& x) = delete;
Student& checkStudent(string account) { //根据学号获取学生信息
Student* p = student_head;
while (p != nullptr)
{
if (p->account == account) {
cout << "此学生在本班中!" << endl;
return *p;
}
p = p->next;
}
cout << "此学生不在本班!请确认学生信息!" << endl;
return *student_head;
}
bool changeStudent(string account, int t) { //根据学号改变学生成绩
Student* p = student_head;
while (p != nullptr) {
if (p->account == account) {
p->grade = t;
cout << "学生成绩修改完毕" << endl;
return true;
}
p = p->next;
}
cout << "此学生不在本班中!" << endl;
return false;
}
bool addstudent(string n, string a, string s, int age, int grade){//添加学生
Student* p = student_head;
Student* newstudent = new Student(n, a, s, age, grade);
while (p->next != nullptr) {
p = p->next;
}
p->next = newstudent;
num++;
return true;
}
bool deleteStudent(string account) { //删除学生
Student* p = student_head;
Student* temp = nullptr; //记录父节点
while (p != nullptr) {
if (p->account == account) {
if (p == student_head) {
student_head = student_head->next;
delete p;
num--;
return true;
}
temp->next = p->next;
delete p;
num--;
return true;
}
temp = p;
p = p->next;
}
cout << "此学生不在本班中!" << endl;
return false;
}
bool deleteAll() {
Student* p;
while (student_head != nullptr) {
p = student_head;
student_head = student_head->next;
delete p;
}
return true;
}
void printStudent() const { //打印班级学生信息
Student* p = student_head->next;
while (p != nullptr) {
p->printStudent();
p = p->next;
}
}
void printClass() const { //打印课程信息
cout << "老师姓名:" << teacher_name;
cout << " 课程号:" << class_account;
cout << " 课程名:" << class_name;
cout << " 本科目班级人数:" << num << endl;
}
};
int main() {
string name[4] = { "牛二", "张三", "李四", "王五" };
string account[4] = { "1234.56", "01", "10", "11" };
string sex[3] = { "男", "男", "男" };
Class a(name[0], "高数", account[0]);
for (int i = 1; i < 4; i++) {
a.addstudent(name[i], account[i], sex[i - 1], 21, 100);
}
if (a.changeStudent(account[1], 59)) {
a.checkStudent(account[2]);
a.printClass();
a.printStudent();
a.deleteStudent(account[2]);
a.printClass();
a.printStudent();
a.checkStudent(account[2]);
}
a.deleteAll();
return 0;
}
最后,写文不易,不收藏也请给个赞,谢谢亲~!
(本文仅供学习时参考,如有错误,纯属作者技术不到位,不足之处请多指教,谢谢)