使用类创建链表建立学生管理系统
在学生管理系统中经常需要使用数组来进行对象的储存,对于一些直观的问题,数组确实能够大致的解决,但是数组却不能够很好判断越界问题以及对于数据成员数量的计算,而链表能很好地解决这些问题。
ps:因为学生管理系统可能还需派生出其他的人员,所以使用继承
class Date
{
public:
Date(char nam[5], char num[10]) :name(nam), num(num) { cout << "创建DATE..." << endl; }
char* Getname()const { return name; };//返回它的值让子类可以使用
char* Getnumber()const { return num; };
private:char *name;
char *num;
};
建立一个基类Date
在基类的基础上派生出Student类
ps:类的继承中非常重要的一点是要设置一个Get函数来使下一级能够访问上一级的数据
{
public:
Student(char nam[5], char num[10], char cla) :Date(nam, num), clas(cla) { cout << "创建学生..." << endl; }
char Getclas() const{ return clas; };
void print()const
{
cout << "学生姓名为:" << Getname() << endl;
cout << "学生学号为:" << Getnumber() << endl;
cout << "学生班级为" << Getclas() << endl;
}
private:
char clas;
};
开始建立链表,先建立节点类
class Node
{
public:
Node(Student* pNode) :itsDate(pNode), itsnext(0) { cout << "节点构造成功" << endl; }
~Node() { delete itsDate; itsDate = 0; } //销毁对象数据
void SetNext(Node* next) { itsnext =next; }//记住下一个节点的地址 ps:为了方便以后链接节点
Node* GetNext()const { return itsnext; }//返回节点
private:
Student* itsDate;
Node* itsnext;
};
链表类
具有增,删,查,显示
class List
{
public:
List() :head(0), count(0) { }//构造函数赋初值
~List();//析构函数
void show();//打印所有数的值函数
int GetCount()const { return count; }//返回该链表节点个数
void Insert(Student* pDate);//将该节点插入链表
void Delete(char* num);//删除名为num的节点
Student* Find(char* num)const;//找到并打印num
private:
Node* head;
int count;
};
链表函数的实现
析构函数
List::~List()
{
Node* l = head;//记录链表头指针位置
Node* m = 0;//交换时需要用到的的中间值
int n = 0;//显示正在删除第几个值
while (l)
{
m = l;
l = l->GetNext();//不断循环
delete m;
n++;
cout << "删除第" << n << "个节点" << endl;
}
增:采用头插法插入节点
void List::Insert(Student* pDate)
{
Node* pn = new Node(pDate);//将new出来的节点赋值给pn PS:pn为所链接的节点
Node* pnow = head; // 传递head
Node* pnext = 0; //定义一个NODE
if (!pnow) //如果头指针没有数值
{
head = pn;
count = 1;
cout << "头结点创建成功" << endl;
return;
}
else {
count++;//个数加1
//头插法
pnext = head->GetNext();//把head的next指针赋值给pnext
pn->SetNext(pnext); //将head的next赋值给pn的next
head->SetNext(pn); //将head的next设置为pn 完成链接
cout << "插入成功" << endl;
}
删:这里使用名字进行删除
void List::Delete(char *num)//删除名为num的
{
Node* pback = head; //传入链表头
Node* pnow = head; //传入链表头
if (!head)
{
cout << "没有数据可删除" << endl;
}
else
{
while (pnow)
{
if (!( strcmp(pnow->Getdate()->Getnumber(), num)))
{
pback->SetNext(pnow->GetNext());//把pback的next设置为head的next
if (pnow == head)//特别注意,如果是边界节点的情况
{
head = head->GetNext();//**头指针指向下一位
cout << "删除头结点" << endl;
}
delete pnow;
pnow = NULL;
count--;
cout << "删除成功" << endl;
return;
}
else
{
pback = pnow;
pnow = pnow->GetNext();
cout << "继续寻找" << endl;
}
}
}
}
查
Student* List::Find(char *name)const//找到并打印该值
{
Node* pn = 0;
for (pn = head; pn != NULL; pn = pn->GetNext())//从头到尾
{
if (!(strcmp(pn->Getdate()->Getname(), name)))//对比
{
cout << "成功找到" << endl;
pn->Getdate()->print();//找到该值并打印
break;
}
}
if (pn == NULL)//若为空则返回空
return NULL;
}
这里的链表基本功能已经具备,但是要进行学生管理系统还需要建立一个菜单类。
class Menu:public List
{
public:
void rinsert(Student* newdate);//输入函数
void run();//运行函数
private:
};
函数的实现
void Menu::run()
{
Student* pDate = 0;
char number[10];
char name[5];
char clas;
int choice;
bool quit = false;
while (1)
{
system("cls");//清屏
cout << "1)增加学生 2)删除学生 3)查找学生 4)学生数目 5)退出" << endl;
cin >> choice;
switch (choice)
{
case 1:
while (1)
{
cout << "添加学生:";
cout << "请输入姓名:";
char* pname = new char;ps:特别注意,该处如果是直接赋值,当输入下一个数的时候,第一个刚刚输入的数也会改变,因为是对地址进行操作,所以需要new。
cin >>pname;
cout << "请输入编号:";
char *pnumber = new char ;
cin >> pnumber;
cout << "请输入班级";
cin >> clas;
pDate = new Student(pname,pnumber, clas);
rinsert(pDate);
cout << "0.return 1.continue" << endl;
cin >> choice;
if (!choice)
{
break;
}
}
break;
case 2:
cout << "请输入您要删除的学生编号:" << endl;
cin >> number;
Delete(number);
cin.get();
break;
case 3:
cout << "请输入要查找的学生的名字" << endl;
cin >> name;
Find(name);
break;
case 4:
cout << "该链表共有" << GetCount() << "个节点" << endl;
show();
break;
case 5:
quit = true;
break;
default: break;
}
if (quit)
{
cout << "程序结束" << endl;
break;
}
}
}
记录一下自己的血泪史,大致就是这样吧,如果有什么不足的地方请指出,我会改进的。