学习教材:王红梅《数据结构——从概念到C++实现》、严蔚敏《数据结构》
学习课程:青岛大学王卓《数据结构与算法基础》
分类专栏:数据结构与算法(C++)
目录
前言
最近刚在学习《数据结构与算法》,单纯地跟课、看书觉得并不能很好的掌握好这些知识点,所以决定尝试将学习的知识点归纳总结,也将其进行代码实现,强化对知识点的理解。即作为笔记、实践,又作为我的思路分享。因为初学,难免有不正确、不恰当之处,敬请指正!
正文
1.栈的介绍
1.1 栈的概述
栈(stack)是限定仅在表的一端进行插入和删除操作的线性表,允许插入和删除的一端称为栈顶(stack top),另一端为栈底(stack bottom),不含任何数据元素的栈称为空栈。跟据存储结构的不同,栈同样可以分为顺序栈和链栈两种。
1.2 栈的特点
栈可以理解为一种功能受限的线性表,因此栈中的元素同样具有线性关系。但因为其只能通过一端进行元素的插入和删除,入栈、出栈具有顺序性,因此栈还具有“后进先出”的特性。
举个简单的例子:一把枪我们填入子弹后,如果要将最底下(也就是最先放入)的子弹取出来的话,我们需要把在它之后填入的子弹按照顺序取出,即“后进先出”。
2.栈的基本实现及设计
2.1 顺序栈设计
2.1.1 数据类型设计
首先定义一个模板类SeqStack,其成员变量有两个,一个是存储数据的数组data,一个是存储顺序栈栈顶元素序号的变量top,为保证数据的安全性,均将权限设为私有。为实现数据的一系列操作,又创建了相应的成员函数,将其权限设置为公有,作为成员变量的接口,供测试者使用。
#define MAXSIZE 100 // 顺序栈最多可以存储多少个元素,可按要求更改
template<typename DataType>
class SeqStack
{
public:
SeqStack(); // 构造函数,初始化一个空栈
~SeqStack() {}; // 析构函数
void CreateSeqStack();
void Push(DataType x); // 入栈操作,将元素x入栈
DataType Pop(); // 出栈操作,将栈顶元素弹出,并返回弹出的元素值
DataType GetTop(); // 取出栈顶元素(并不删除)
int Length(); // 求顺序栈长度
int Empty(); // 判空操作
void PrintStack(); // 遍历打印,按照出栈顺序打印
private:
DataType data[MAXSIZE]; // 存储元素的数据
int top; // 存储栈顶元素的下标
};
2.1.2 算法设计
(1)构造函数
即将顺序栈进行初始化,只需将栈顶指针top置为-1即可。
template<typename DataType>
SeqStack<DataType>::SeqStack()
{
this->top = -1;
}
(2)析构函数
顺序栈为静态存储分配,在顺序栈变量退出作用域时,将自动释放顺序栈所占存储空间,因此无须销毁,析构函数为空。
(3)入栈操作
首先应判断栈是否为满,即top+1是否等于 MAXSIZE 。若未满, 在栈中插入元素n只需要将栈顶位置加1,然后在data[top]的位置填入元素x。
template<typename DataType>
void SeqStack<DataType>::Push(DataType x)
{
if (this->top+1 == MAXSIZE) throw"上溢";
this->data[top + 1] = x;
this->top++;
}
(4)创建指定长度的顺序栈
创建长度为n的顺序栈,即按照输入顺序,对一个空栈进行n次入栈。
template<typename DataType>
void SeqStack<DataType>::CreateSeqStack()
{
int num, value;
cout << "请输入要入栈的元素个数:";
cin >> num;
cout << "请输入要入栈的元素数值:";
for (int i = 0; i < num; i++)
{
cin >> value;
this->data[i] = value;
this->top++;
}
}
(5)判空操作
判空操作只需要判断顺序栈类成员函数top是否等于-1,即 this->top==-1。
template<typename DataType>
int SeqStack<DataType>::Empty()
{
if (this->top==-1)
return 1;
else
return 0;
}
(6)出栈操作
将一个元素从顺序栈中删除,即出栈,首先应判断栈是否为空,即this->Empty()是否等于1。若栈非空,出栈操作只需取出栈顶元素,然后top再减1。
template<typename DataType>
DataType SeqStack<DataType>::Pop()
{
DataType y;
if (this->Empty() == 1) throw"下溢";
y = this->data[top];
this->top--;
return y;
}
(7)取出栈顶元素(不删除)
取栈顶元素只是将top位置的栈顶元素取出并返回,并不改变栈本身。
template<typename DataType>
DataType SeqStack<DataType>::GetTop()
{
DataType y;
if (this->Length() == 0) throw"下溢";
// if (this->Empty == 1) throw"下溢";
y = this->data[top];
return y;
}
(8)输出顺序栈长度
输出顺序栈的长度,就是将top加1后再返回。
template<typename DataType>
int SeqStack<DataType>::Length()
{
return this->top+1;
}
(9)遍历打印顺序栈当前元素
通过前面所写的Length(),得到顺序栈的长度,使用循环,从栈底开始遍历打印。
template<typename datatype>
void SeqStack<datatype>::PrintStack()
{
int length = this->Length();
if (length > 0)
{
for (int i = 0; i < length; i++)
cout <<this->data[i] << " ";
cout << endl;
}
else
cout << "顺序栈为空" << endl;
}
2.2 链栈设计
2.2.1 数据类型设计
首先使用结构体创建LinkedNode数据类型,定义了结点,包括指针域next和数据域data。随后定义链栈类LinkedStack,其成员变量为LinkedNode类型的指针top,为保证数据的安全性,将权限设为私有。为实现数据的一系列操作,又创建了相应的成员函数,将其权限设置为公有,作为成员变量的接口,供测试者使用。
// 定义了LinkNode结点
template<typename DataType>
struct LinkNode {
DataType data;//数据域
LinkNode<DataType>* next;//指针域
};
template<typename DataType>
class LinkedStack
{
public:
LinkedStack() { top = NULL; } // 构造函数,初始化一个空栈
~LinkedStack(); // 析构函数
void CreateLinkedStack();
void Push(DataType x); // 入栈操作,将元素x入栈
DataType Pop(); // 出栈操作,将栈顶元素弹出,并返回弹出的元素值
DataType GetTop(); // 取出栈顶元素(并不删除)
int Length(); // 求顺序栈长度
int Empty(); // 判空操作
void PrintStack(); // 遍历打印,按照出栈顺序打印
private:
LinkNode<DataType>* top;
};
2.2.2 算法设计
(1)构造函数
链栈不带头结点,初始化一个空链栈只需将栈顶指针top置空。
template<typename DataType>
LinkedStack<DataType>::LinkedStack()
{
top = NULL;
}
(2)析构函数
链栈为动态存储分配,在链栈变量退出作用域前要释放链栈的存储空间。
template<typename DataType>
LinkedStack<DataType>::~LinkedStack()
{
LinkNode<DataType>* p = top;
while (this->top)
{
top = top->next;
delete p;
p = top;
}
}
(3)入栈操作
链栈的插入只需处理栈顶的情况,先申请一个新结点s,在其数据域中存入入栈元素、指针域存入top的地址,再使top=s。
template<typename DataType>
void LinkedStack<DataType>::Push(DataType x)
{
// 申请一个数据域为x的结点s
LinkNode<DataType>* s = new LinkNode<DataType>;
if (!s)
{
cout << "分配内存失败";
return;
}
s->data = x;
s->next = top;
top = s;
}
(4)创建指定长度的链栈
创建长度为n的链栈,即按照输入顺序,对一个空链栈进行n次入栈。
template<typename DataType>
void LinkedStack<DataType>::CreateLinkedStack()
{
this->top = nullptr;
LinkNode<DataType>* s = nullptr;
int num, value;
cout << "请输入要创建的链栈长度:";
cin >> num;
cout << "请输入入栈的元素数值:";
for (int i = 0; i < num; i++)
{
cin >> value;
LinkNode<DataType>* newNode = new LinkNode<DataType>;
newNode->data = value;
newNode->next = top;
top = newNode;
}
}
(5)出栈操作
链栈的删除操作只需处理栈顶的情况,创建一个临时结点temp,使temp=top,将栈顶元素取出,随后使top=top->next,使栈顶指针top指向下一结点。将temp的数据域取出存于新定义的变量y中,随后释放结点temp(原栈顶元素)。
template<typename DataType>
DataType LinkedStack<DataType>::Pop()
{
if (this->Empty() == 1) throw"下溢";
LinkNode<DataType>* temp = top;
top = top->next;
int y = temp->data;
delete temp;
return y;
}
(6)输出链栈长度
定义了变量length用于计数,在循环中遍历链栈,直至到栈底元素为止,判定的依据为结点的next域为空。
template<typename DataType>
int LinkedStack<DataType>::Length()
{
int length = 0;
LinkNode<DataType>* current = this->top;
while (current != nullptr) {
current = current->next;
length++;
}
return length;
}
(7)判空操作
使用前面所写的Length()函数进行判空。
template<typename DataType>
int LinkedStack<DataType>::Empty()
{
if (this->Length() == 0)
{
return 1;
}
else
return 0;
}
(8)取出栈顶元素(不删除)
取栈顶元素只需返回栈顶指针top所指结点的数据域,并不修改栈顶指针。
template<typename DataType>
DataType LinkedStack<DataType>::GetTop()
{
if (this->Empty() == 1) throw"下溢";
return top->data;
}
(9)遍历打印链栈当前元素
template<typename DataType>
void LinkedStack<DataType>::PrintStack()
{
LinkNode<DataType>* current = this->top;
cout << "当前链表中的元素为:";
while (current != nullptr) {
cout << current->data << " ";
current = current->next;
}
cout << endl;
}
2.3 菜单设计
2.3.1 主页面菜单设计
主页面菜单(即一级菜单)使用switch-case语句实现。先定义一个choice_one变量,将输入的数值存入,通过判断choice_one来进入不同二级页面或退出。
int choice_one;
choice_one = -1;
while (choice_one != 0)
{
cout << "栈示例:" << endl;
cout << "1. 顺序栈功能实现" << endl;
cout << "2. 链栈功能实现" << endl;
cout << "0. 退出" << endl;
cout << "请选择:" << endl;
cin >> choice_one;
system("cls");
switch (choice_one)
{
case 1://
SeqStackMenu();
system("pause");
system("cls");
break;
case 2://
LinkedStackMenu();
system("pause");
system("cls");
break;
case 0: // 0.退出
cout << "欢迎下次使用!" << endl;
system("pause");
return 0;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
2.3.2 二级页面菜单设计
因为二级菜单内容较多,并未和一级菜单写在一个文件中,而是采取了分文件编写的思想,创建了my_menu.cpp和My_menu.h,将二级菜单存入其中。顺序栈和链栈的功能菜单分别写成函数,然后再直接在一级菜单中进行调用。为区分开,二级菜单定义了新的变量choice_two,用来存储二级菜单的选择数值。
// 顺序栈的功能菜单
void SeqStackMenu()
{
SeqStack<int> Seq;
/* 注意重置choice_two的值,否则将会再次进入会变为0,无法开始循环 */
int choice_two = -1;
while (choice_two)
{
cout << "顺序栈示例:" << endl;
cout << "1. 创建指定长度的顺序栈" << endl;
cout << "2. 将指定元素入栈" << endl;
cout << "3. 弹出栈顶元素" << endl;
cout << "4. 输出栈顶元素数值" << endl;
cout << "5. 输出顺序栈的长度" << endl;
cout << "6. 遍历打印顺序栈" << endl;
cout << "0. 返回上一级菜单" << endl;
cout << "请选择:" << endl;
cin >> choice_two;
switch (choice_two)
{
case 1:
try
{
Seq.CreateSeqStack();
cout << "顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 2:
try
{
int value;
cout << "请输入将要入栈的元素数值" << endl;
cin >> value;
Seq.Push(value);
cout << "顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 3:
try
{
int value = Seq.Pop();
cout << "弹出的栈顶元素的数值为:" << value << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 4:
try
{
cout << "当前顺序栈的栈顶元素数值为:" << Seq.GetTop() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 5:
try
{
cout << "当前顺序栈的长度为:" << Seq.Length() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 6:
try
{
cout << "当前顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 0:
cout << "退出顺序栈功能菜单!" << endl;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
}
// 链栈的功能菜单
void LinkedStackMenu()
{
LinkedStack<int> Link;
int choice_two = -1;
while (choice_two)
{
cout << "链栈示例:" << endl;
cout << "1. 创建指定长度的链栈" << endl;
cout << "2. 将指定元素入栈" << endl;
cout << "3. 弹出栈顶元素" << endl;
cout << "4. 输出栈顶元素数值" << endl;
cout << "5. 输出链栈的长度" << endl;
cout << "6. 遍历打印链栈" << endl;
cout << "0. 返回上一级菜单" << endl;
cout << "请选择:" << endl;
cin >> choice_two;
switch(choice_two)
{
case 1:
try
{
Link.CreateLinkedStack();
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 2:
try
{
int value;
cout << "请输入将入栈的元素数值:";
cin >> value;
Link.Push(value);
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 3:
try
{
int value = Link.Pop();
cout << "弹出的栈顶元素数值为:" << value << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 4:
try
{
cout << "栈顶元素的数值为:" << Link.GetTop() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 5:
try
{
int length = Link.Length();
cout << "当前链表的长度为:" << length << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 6:
try
{
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 0:
cout << "退出链栈功能菜单!" << endl;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
}
3.全部代码(分文件编写)
SeqStack.h
#pragma once
#include<iostream>
using namespace std;
#ifndef SeqStack_H
#define SeqStack_H
#define MAXSIZE 100 // 顺序栈最多可以存储多少个元素,可按要求更改
template<typename DataType>
class SeqStack
{
public:
SeqStack(); // 构造函数,初始化一个空栈
~SeqStack() {}; // 析构函数
void CreateSeqStack();
void Push(DataType x); // 入栈操作,将元素x入栈
DataType Pop(); // 出栈操作,将栈顶元素弹出,并返回弹出的元素值
DataType GetTop(); // 取出栈顶元素(并不删除)
int Length(); // 求顺序栈长度
int Empty(); // 判空操作
void PrintStack(); // 遍历打印,按照出栈顺序打印
private:
DataType data[MAXSIZE];
int top;
};
#endif
SeqStack.cpp
#include "SeqStack.h"
//*****************************************************
//函数名:SeqStack
//函数功能:构造函数,初始化一个空栈
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
template<typename DataType>
SeqStack<DataType>::SeqStack()
{
this->top = -1;
}
//*****************************************************
//函数名:CreateSeqStack
//函数功能:创建一个指定长度的顺序栈
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
template<typename DataType>
void SeqStack<DataType>::CreateSeqStack()
{
int num, value;
cout << "请输入要入栈的元素个数:";
cin >> num;
cout << "请输入要入栈的元素数值:";
for (int i = 0; i < num; i++)
{
cin >> value;
this->data[i] = value;
this->top++;
}
}
//*****************************************************
//函数名:Push
//函数功能:入栈操作,将元素x入栈
//输入参数:
// DataType,x,即将入栈的元素数值
//输出参数:
// 无
//******************************************************
template<typename DataType>
void SeqStack<DataType>::Push(DataType x)
{
if (this->top+1 == MAXSIZE) throw"上溢";
this->data[top + 1] = x;
this->top++;
}
//*****************************************************
//函数名:Pop
//函数功能:出栈操作,将栈顶元素弹出,并返回弹出的元素值
//输入参数:
// 无
//输出参数:
// DataType,弹出元素的数值
//******************************************************
template<typename DataType>
DataType SeqStack<DataType>::Pop()
{
DataType y;
if (this->Empty() == 1) throw"下溢";
y = this->data[top];
this->top--;
return y;
}
//*****************************************************
//函数名:GetTop
//函数功能:取出栈顶元素(并不删除)
//输入参数:
// 无
//输出参数:
// DataType,栈顶元素的数值
//******************************************************
template<typename DataType>
DataType SeqStack<DataType>::GetTop()
{
DataType y;
if (this->Length() == 0) throw"下溢";
// if (this->Empty == 1) throw"下溢";
y = this->data[top];
return y;
}
//*****************************************************
//函数名:Length
//函数功能:输出栈的长度
//输入参数:
// 无
//输出参数:
// int,栈的长度
//******************************************************
template<typename DataType>
int SeqStack<DataType>::Length()
{
return this->top+1;
}
//*****************************************************
//函数名:Empty
//函数功能:判断栈是否为空
//输入参数:
// 无
//输出参数:
// 1,代表栈为空;0,代表栈非空
//******************************************************
template<typename DataType>
int SeqStack<DataType>::Empty()
{
if (this->top==-1)
return 1;
else
return 0;
}
//*****************************************************
//函数名:PrintStack
//函数功能:遍历打印栈
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
template<typename datatype>
void SeqStack<datatype>::PrintStack()
{
int length = this->Length();
if (length > 0)
{
for (int i = 0; i < length; i++)
cout <<this->data[i] << " ";
cout << endl;
}
else
cout << "顺序栈为空" << endl;
}
LinkedStack.h
#pragma once
#include<iostream>
using namespace std;
#ifndef LinkedStack_H
#define LinkedStack_H
template<typename DataType>
struct LinkNode {
DataType data;//数据域
LinkNode<DataType>* next;//指针域
};
template<typename DataType>
class LinkedStack
{
public:
LinkedStack() { top = NULL; } // 构造函数,初始化一个空栈
~LinkedStack(); // 析构函数
void CreateLinkedStack();
void Push(DataType x); // 入栈操作,将元素x入栈
DataType Pop(); // 出栈操作,将栈顶元素弹出,并返回弹出的元素值
DataType GetTop(); // 取出栈顶元素(并不删除)
int Length(); // 求顺序栈长度
int Empty(); // 判空操作
void PrintStack(); // 遍历打印,按照出栈顺序打印
private:
LinkNode<DataType>* top;
};
#endif
LinkedStack.cpp
#include "LinkedStack.h"
// 析构函数
template<typename DataType>
LinkedStack<DataType>::~LinkedStack()
{
LinkNode<DataType>* p = top;
while (this->top)
{
top = top->next;
delete p;
p = top;
}
}
//*****************************************************
//函数名:CreateLinkedStack
//函数功能:创建一个指定长度的链栈
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
template<typename DataType>
void LinkedStack<DataType>::CreateLinkedStack()
{
this->top = nullptr;
LinkNode<DataType>* s = nullptr;
int num, value;
cout << "请输入要创建的链栈长度:";
cin >> num;
cout << "请输入入栈的元素数值:";
for (int i = 0; i < num; i++)
{
cin >> value;
LinkNode<DataType>* newNode = new LinkNode<DataType>;
newNode->data = value;
newNode->next = top;
top = newNode;
}
}
//*****************************************************
//函数名:Push
//函数功能:入栈操作,将元素x入栈
//输入参数:
// DataType,x,即将入栈的元素数值
//输出参数:
// 无
//******************************************************
template<typename DataType>
void LinkedStack<DataType>::Push(DataType x)
{
// 申请一个数据域为x的结点s
LinkNode<DataType>* s = new LinkNode<DataType>;
if (!s)
{
cout << "分配内存失败";
return;
}
s->data = x;
s->next = top;
top = s;
}
//*****************************************************
//函数名:Pop
//函数功能:出栈操作,将栈顶元素弹出,并返回弹出的元素值
//输入参数:
// 无
//输出参数:
// DataType,弹出元素的数值
//******************************************************
template<typename DataType>
DataType LinkedStack<DataType>::Pop()
{
if (this->Empty() == 1) throw"下溢";
LinkNode<DataType>* temp = top;
top = top->next;
int y = temp->data;
delete temp;
return y;
}
//*****************************************************
//函数名:GetTop
//函数功能:取出栈顶元素(并不删除)
//输入参数:
// 无
//输出参数:
// DataType,栈顶元素的数值
//******************************************************
template<typename DataType>
DataType LinkedStack<DataType>::GetTop()
{
if (this->Empty() == 1) throw"下溢";
return top->data;
}
//*****************************************************
//函数名:Empty
//函数功能:判断栈是否为空
//输入参数:
// 无
//输出参数:
// 1,代表栈为空;0,代表栈非空
//******************************************************
template<typename DataType>
int LinkedStack<DataType>::Empty()
{
if (this->Length() == 0)
{
return 1;
}
else
return 0;
}
//*****************************************************
//函数名:Length
//函数功能:输出栈的长度
//输入参数:
// 无
//输出参数:
// int,栈的长度
//******************************************************
template<typename DataType>
int LinkedStack<DataType>::Length()
{
int length = 0;
LinkNode<DataType>* current = this->top;
while (current != nullptr) {
current = current->next;
length++;
}
return length;
}
//*****************************************************
//函数名:PrintStack
//函数功能:遍历打印栈
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
template<typename DataType>
void LinkedStack<DataType>::PrintStack()
{
LinkNode<DataType>* current = this->top;
cout << "当前链表中的元素为:";
while (current != nullptr) {
cout << current->data << " ";
current = current->next;
}
cout << endl;
}
my_Menu.h
#pragma once
#include<iostream>
using namespace std;
#ifndef my_Menu_H
#define my_Menu_H
void SeqStackMenu();
void LinkedStackMenu();
#endif
my_Menu.cpp
#include "my_Menu.h"
#include "SeqStack.cpp"
#include "LinkedStack.cpp"
//*****************************************************
//函数名:SeqStackMenu
//函数功能:顺序栈的功能菜单
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
void SeqStackMenu()
{
SeqStack<int> Seq;
/* 注意重置choice_two的值,否则将会再次进入会变为0,无法开始循环 */
int choice_two = -1;
while (choice_two)
{
cout << "顺序栈示例:" << endl;
cout << "1. 创建指定长度的顺序栈" << endl;
cout << "2. 将指定元素入栈" << endl;
cout << "3. 弹出栈顶元素" << endl;
cout << "4. 输出栈顶元素数值" << endl;
cout << "5. 输出顺序栈的长度" << endl;
cout << "6. 遍历打印顺序栈" << endl;
cout << "0. 返回上一级菜单" << endl;
cout << "请选择:" << endl;
cin >> choice_two;
switch (choice_two)
{
case 1:
try
{
Seq.CreateSeqStack();
cout << "顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 2:
try
{
int value;
cout << "请输入将要入栈的元素数值" << endl;
cin >> value;
Seq.Push(value);
cout << "顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 3:
try
{
int value = Seq.Pop();
cout << "弹出的栈顶元素的数值为:" << value << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 4:
try
{
cout << "当前顺序栈的栈顶元素数值为:" << Seq.GetTop() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 5:
try
{
cout << "当前顺序栈的长度为:" << Seq.Length() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 6:
try
{
cout << "当前顺序栈的元素为:(从栈底开始遍历)" << endl;
Seq.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 0:
cout << "退出顺序栈功能菜单!" << endl;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
}
//*****************************************************
//函数名:LinkedStackMenu
//函数功能:链栈的功能菜单
//输入参数:
// 无
//输出参数:
// 无
//******************************************************
void LinkedStackMenu()
{
LinkedStack<int> Link;
int choice_two = -1;
while (choice_two)
{
cout << "链栈示例:" << endl;
cout << "1. 创建指定长度的链栈" << endl;
cout << "2. 将指定元素入栈" << endl;
cout << "3. 弹出栈顶元素" << endl;
cout << "4. 输出栈顶元素数值" << endl;
cout << "5. 输出链栈的长度" << endl;
cout << "6. 遍历打印链栈" << endl;
cout << "0. 返回上一级菜单" << endl;
cout << "请选择:" << endl;
cin >> choice_two;
switch(choice_two)
{
case 1:
try
{
Link.CreateLinkedStack();
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 2:
try
{
int value;
cout << "请输入将入栈的元素数值:";
cin >> value;
Link.Push(value);
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 3:
try
{
int value = Link.Pop();
cout << "弹出的栈顶元素数值为:" << value << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 4:
try
{
cout << "栈顶元素的数值为:" << Link.GetTop() << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 5:
try
{
int length = Link.Length();
cout << "当前链表的长度为:" << length << endl;
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 6:
try
{
Link.PrintStack();
system("pause");
system("cls");
break;
}
catch (const char* s)
{
cout << s << endl;
system("pause");
system("cls");
break;
}
case 0:
cout << "退出链栈功能菜单!" << endl;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
}
main.cpp
#include<iostream>
#include "SeqStack.cpp"
#include "LinkedStack.cpp"
#include "my_Menu.h"
using namespace std;
int main()
{
int choice_one;
choice_one = -1;
while (choice_one != 0)
{
cout << "栈示例:" << endl;
cout << "1. 顺序栈功能实现" << endl;
cout << "2. 链栈功能实现" << endl;
cout << "0. 退出" << endl;
cout << "请选择:" << endl;
cin >> choice_one;
system("cls");
switch (choice_one)
{
case 1://
SeqStackMenu();
system("pause");
system("cls");
break;
case 2://
LinkedStackMenu();
system("pause");
system("cls");
break;
case 0: // 0.退出
cout << "欢迎下次使用!" << endl;
system("pause");
return 0;
break;
default:
cout << "非法输入,请重新选择!" << endl;
system("pause");
system("cls");
break;
}
}
system("plase");
return 0;
}
初学数据结构与算法,若有不正确之处,敬请指正啦~