c++继承和派生(链表)
题目描述
设计单链表类,并基于单链表类实现栈类和队列类:
(1)设计学生信息类StudentRecord,要求包含公有数据成员:string stuName
和int stuNo
,设计用于输出学生信息的公有成员函数:void print
,输出格式为:Name: stuName, Number: stuNo
(2)设计学生链表的结点类StudentNode,要求包含公有数据成员:StudentRecord data
和StudentNode *next
(3)设计学生链表类LinkedList,要求定义头插入、头删除、尾插入、遍历等公有成员函数
(4)由LinkedList派生LinkedStack类,基于单链表类的功能实现压栈和出栈的成员函数:
void Push(StudentRecord record)
和bool Pop(StudentRecord &record)
(5)由LinkedList派生LinkedQueue类,基于单链表类的功能实现入队和出队的成员函数:
void EnQueue(StudentRecord record)
和bool DeQueue(StudentRecord &record)
。
在main函数中:
定义一个LinkedQueue类的对象queue和一个LinkedStack类的对象stack,并根据用户的输入分别对queue和stack作出相应的操作。若为"Push",则压栈;若为"EnQueue",则入队;若为"Pop",则出栈;若为"DeQueue",则出队;若为"Exit",则退出;若为其它,则给出提示信息"Input error!
"。入栈和入队时,输入学生姓名和学号。出栈和出队时,若非空,则输出被删除的学生信息;若栈空,则输出“Stack is empty!
";若队空,则输出"Queue is empty!
"。
输入
操作名;学生姓名,学号。
输出
删除的信息;提示信息。
样例输入
Push
ZhangSan 200905
Push
LiSi 200906
EnQueue
WangWu 200907
Pop
exit
Exit
样例输出
Name: LiSi, Number: 200906
Input error!
#include <iostream>
#include <string>
using namespace std;
class StudentRecord
{
public:
string stuName;
int stuNo;
StudentRecord(string name, int no){
stuName = name;
stuNo = no;
}
//输出函数
void print() {
cout << "Name: " << stuName << ", "
<< "Number: " << stuNo << endl;
}
StudentRecord(){}
~StudentRecord(){}
};
class StudentNode
{
public:
StudentRecord data;
StudentNode* next;
};
class LinkedList
{
public:
StudentNode* head;
LinkedList() {
head = new StudentNode;
head->next = NULL;
}
~LinkedList(){}
//插入结点 pos==0头插 pos==-1 尾插
void InsertList(StudentNode *node,int pos = 0) {
StudentNode* p = head;
StudentNode* q=node;
if (pos == 0) {
q->next = p->next;
p->next = q;
}
else if (pos == -1) {
while (p->next != NULL) {
p = p->next;
}
p->next = q;
q->next = NULL;
}
}
//删除结点 pos==0头删 pos==-1 尾删
void DeleteList(int pos = 0) {
StudentNode* p = head;
StudentNode* q = NULL;
if (pos == 0) {
q = p->next;
p->next = q->next;
q->next = NULL;
}
else if (pos == -1) {
while (p->next!= NULL) {
q = p;
p = p->next;
}
q->next = NULL;
}
}
};
//栈
class LinkedStack : public LinkedList
{
public:
//压栈
void Push(StudentRecord record) {
StudentNode* node=new StudentNode;
node->data = record;
InsertList(node, 0);
}
//出栈
bool Pop(StudentRecord& record){
StudentNode* p;
if (head->next == NULL) {
cout << "Stack is empty!" << endl;
return false;
}else {
p = head->next;
record = p->data;
DeleteList(0);
return true;
}
}
LinkedStack() {}
~LinkedStack() {}
};
//队列
class LinkedQueue :public LinkedList
{
public:
void EnQueue(StudentRecord record){
StudentNode* node=new StudentNode;
node->data = record;
InsertList(node, -1);
}
bool DeQueue(StudentRecord& record){
StudentNode* p;
if (head->next == NULL) {
cout << "Queue is empty!" << endl;
return false;
}
else {
p = head->next;
record = p->data;
DeleteList(0);
return true;
}
}
LinkedQueue(){}
~LinkedQueue() {}
};
int main()
{
LinkedQueue queue;
LinkedStack stack;
string style;
cin >> style;
while (style != "Exit") {
if (style == "Push") {
string Name;
int No;
cin >> Name >> No;
StudentRecord p(Name, No);
stack.Push(p);
}
else if (style == "Pop") {
StudentRecord record;
bool flag=stack.Pop(record);
if(flag){
record.print();
}
}
else if (style == "EnQueue") {
string Name;
int No;
cin >> Name >> No;
StudentRecord p(Name, No);
queue.EnQueue(p);
}
else if (style == "DeQueue") {
StudentRecord record;
bool flag=queue.DeQueue(record);
if(flag){
record.print();
}
}
else if (style == "Exit") {
return 0;
}
else {
cout << "Input error!" <<endl;
}
cin >> style;
}
}
总结
- 可以引入
int pos
判断结点位置,默认pos==0
为头,pos==-1
为尾,其他情况为中间。 - 一定要注意链表构造的栈或队列为空的情况,判断是否为空,再做操作。