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!"。

class StudentRecord{//学生数据类

private:

string stuName;

int stuNo;

public:

void print()

{

cout<<"Name: "<<stuName<<", Number: "<<stuNo<<endl;

}

StudentRecord& operator=(const StudentRecord &stu)//重载等号

{

stuName=stu.stuName;

stuNo=stu.stuNo;

return *this;

}

void setData(string str,int no)//赋值操作

{

stuName=str;

stuNo=no;

}

friend class LinkedList;

};

class StudentNode{//结点类

public:

StudentRecord data;

StudentNode *next;

StudentNode()

{

next=NULL;

}

};

在链表类中把出栈、出队统一为函数bool deleteNode(),把获取栈中、队中的一个结点数据统一为函数bool getData(StudentRecord &record)。

class LinkedList{//单链表类

protected:

StudentNode *head,*tail;

public:

LinkedList()//创建链表

{

head=tail=new StudentNode;

head->next=NULL;

(head->data).setData("head_node",0);

}

~LinkedList()//删除链表

{

StudentNode *temp;

while(head!=tail)

{

temp=head;

head=head->next;

delete temp;

}

delete head;

}

void headAdd(StudentNode &node)//头插入结点

{

node.next=head;

head=&node;

}

bool deleteNode()//从头删除一个结点

{

if(empty()){

return false;//删除失败

}

StudentNode *temp;

if((head->data).stuName=="head_node"){//如果是尾插

if((head->next)->next==NULL){//如果只有一个结点(除头结点)

tail=head;

temp=head->next;

head->next=NULL;

delete temp;

return true;//删除成功

}

else{//如果多于1个结点(除头结点)

temp=head->next;

head->next=(head->next)->next;

delete temp;

return true;//删除成功

}

}

else{//如果是头插

temp=head;

head=head->next;

delete temp;

return true;//删除成功

}

}

void tailAdd(StudentNode &node)//尾插入结点

{

tail->next=&node;

tail=&node;

}

bool empty()//判断链表是否为空

{

if(head==tail){

return true;

}

else return false;

}

bool getData(StudentRecord &record)//获取链表中第一个数据

{

if(empty()){

return false;//获取失败

}

if((head->data).stuName=="head_node"){

record=(head->next)->data;

return true;//获取成功

}

else{

record=head->data;

return true;//获取成功

}

}

};

class LinkedList{//单链表类

protected:

StudentNode *head,*tail;

public:

LinkedList()//创建链表

{

head=tail=new StudentNode;

head->next=NULL;

(head->data).setData("head_node",0);

}

~LinkedList()//删除链表

{

StudentNode *temp;

while(head!=tail)

{

temp=head;

head=head->next;

delete temp;

}

delete head;

}

void headAdd(StudentNode &node)//头插入结点

{

node.next=head;

head=&node;

}

bool deleteNode()//从头删除一个结点

{

if(empty()){

return false;//删除失败

}

StudentNode *temp;

if((head->data).stuName=="head_node"){//如果是尾插

if((head->next)->next==NULL){//如果只有一个结点(除头结点)

tail=head;

temp=head->next;

head->next=NULL;

delete temp;

return true;//删除成功

}

else{//如果多于1个结点(除头结点)

temp=head->next;

head->next=(head->next)->next;

delete temp;

return true;//删除成功

}

}

else{//如果是头插

temp=head;

head=head->next;

delete temp;

return true;//删除成功

}

}

void tailAdd(StudentNode &node)//尾插入结点

{

tail->next=&node;

tail=&node;

}

bool empty()//判断链表是否为空

{

if(head==tail){

return true;

}

else return false;

}

bool getData(StudentRecord &record)//获取链表中第一个数据

{

if(empty()){

return false;//获取失败

}

if((head->data).stuName=="head_node"){

record=(head->next)->data;

return true;//获取成功

}

else{

record=head->data;

return true;//获取成功

}

}

};

#include <iostream>

#include <string>

using namespace std;

int main()

{

LinkedQueue queue;

LinkedStack stack;

//signal用来获取操作,name用来接受学生姓名

string signal,name;

//number用来接收学生学号

int number;

//save用来保存结点数据

StudentRecord save;

cin>>signal;

while(signal!="Exit")

{

//操作为入栈或入队

if(signal=="Push"||signal=="EnQueue"){

cin>>name>>number;//接收数据

save.setData(name,number);//获得结点数据

if(signal=="Push"){//入栈操作

stack.Push(save);//结点入栈

}

else queue.EnQueue(save);//入队操作,结点入队

cin>>signal;//获取下一个操作

continue;

}

//操作为出栈或出队

if(signal=="Pop"||signal=="DeQueue"){

if(signal=="Pop"){//出栈操作

if(stack.Pop(save)){//成功出栈

save.print();//打印出栈结点数据

}

else cout<<"Stack is empty!"<<endl;

}

else{//出队操作

if(queue.DeQueue(save)){//成功出队

save.print();//打印出队结点数据

}

else cout<<"Queue is empty!"<<endl;

}

cin>>signal;//获取下一个操作

continue;

}

//不是入栈、入队,不是出栈、出队,也不是退出程序

cout<<"Input error!"<<endl;

cin>>signal;

}

return 0;

}

总结:

使用派生类时,三种继承方式的用途:

1.希望派生类仅能在类内访问父类protected成员,并能用对象来访问父类public成员,用public继承方式;

2.希望派生类仅能在类内访问父类public、protected成员,用protected继承方式;

3.希望派生类类内类外都无法访问父类protected、public成员,用private继承方式。

字类不继承父类构造函数,但是如果没有给子类写构造函数,编译器将会调用父类的构造函数(根据具体情况,可能报错可能不报错)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值