一、实验目的
熟练掌栈的结构特点,掌握栈的顺序存储和链式存储结构和实现。
二、实验内容
1.用C++的模板来实现顺序栈,下面是代码:
SeqStack.h
#ifndef SeqStack_h
#define SeqStack_h
#include <iostream>
using namespace std;
const int StackSize = 100;
template <class DataType>
class SeqStack {
public:
// 构造函数 初始化一个空栈
SeqStack() { top = -1; }
// 析构函数
~SeqStack() {}
// 入栈
void Push(DataType x);
// 出栈
DataType Pop();
// 去栈顶元素
DataType GetTop();
// 判断是否为空
bool isEmpty() { return top == -1 ? true : false;}
// 输出栈
void PrintStack();
private:
DataType data[StackSize];
int top;
};
#endif /* SeqStack_h */
SeqStack.cpp
#include "SeqStack.h"
template <class DataType>
void SeqStack<DataType>::Push(DataType x) {
if (top == StackSize-1) throw "上溢";
data[++top] = x;
}
template <class DataType>
DataType SeqStack<DataType>::Pop() {
if (top == -1) throw "下溢";
DataType x = data[top--];
return x;
}
template <class DataType>
DataType SeqStack<DataType>::GetTop() {
if (top == -1) throw "空栈";
return data[top];
}
template <class DataType>
void SeqStack<DataType>::PrintStack() {
// cout << data[top];
cout << "===" << endl;
cout << "top" << endl;
int p = top;
while (p != 0) {
cout << " " << data[p--] << endl;
}
cout << "===" << endl;
}
设计了一个输出当前栈中元素的PrintStack函数,并且给了个简单的界面,方便了调试和对栈的理解。下面是用了一些数据来测试了这个模板。
main.cpp
#include <iostream>
#include "SeqStack.cpp"
int main(int argc, const char * argv[]) {
SeqStack<int> stack = SeqStack<int>();
cout << "isEmpty : " << stack.isEmpty() << endl;
for (int i = 0; i < 10; i++) {
stack.Push(i);
}
stack.PrintStack();
cout << "isEmpty : " << stack.isEmpty() << endl;
cout << "GetTop : " <<stack.GetTop() << endl;
cout << "Pop : " << stack.Pop() << endl;
cout << "Pop : " << stack.Pop() << endl;
stack.PrintStack();
cout << "GetTop : " <<stack.GetTop() << endl;
return 0;
}
控制台输出如下:
2.用C++的模板来实现链栈,下面是代码:
LinkStack.h
#ifndef LinkStack_h
#define LinkStack_h
#include <iostream>
using namespace std;
template<class DataType>
struct Node {
DataType data;
Node<DataType> *next;
Node<DataType>(DataType x) {
data = x;
next = NULL;
}
};
template <class DataType>
class LinkStack {
public:
// 构造函数 初始化一个空栈
LinkStack() { top = NULL; }
// 析构函数
~LinkStack() {}
// 入栈
void Push(DataType x);
// 出栈
DataType Pop();
// 去栈顶元素
DataType GetTop();
// 判断是否为空
bool isEmpty() { return top == NULL ? true : false;}
// 输出栈
void PrintStack();
private:
// 栈顶指针
Node<DataType> *top;
};
#endif /* LinkStack_h */
LinkStack.cpp
#include "LinkStack.h"
template <class DataType>
void LinkStack<DataType>::Push(DataType x) {
Node<DataType> *s = new Node<DataType>(x);
s -> next = top; // 将结点插在栈顶
top = s;
}
template <class DataType>
DataType LinkStack<DataType>::Pop() {
if (top == NULL) throw "下溢";
DataType x = top -> data;
Node<DataType> *p = top;
top = top -> next;
delete p;
return x;
}
template <class DataType>
DataType LinkStack<DataType>::GetTop() {
if (top == NULL) throw "空栈";
return top -> data;
}
template <class DataType>
void LinkStack<DataType>::PrintStack() {
if (top == NULL) {
cout << "空栈" << endl;
return;
}
}
以上是模板的 代码,原本也想在链栈做一个输出函数,但是由于没有完全掌握他的设计结构,写起来比较费劲,就日后再补充上去了。当然了,用模板也是为了日后继续修改,争取了写出好的模板,这样对链表的也能有更深的理解,对开发十分有好处。下面是用了一些数据来测试这个模板,先上主文件的代码。
main.h
#include <iostream>
#include "LinkStack.cpp"
int main(int argc, const char * argv[]) {
LinkStack<int> stack = LinkStack<int>();
for (int i = 0; i < 10; i++) {
stack.Push(i);
}
cout << stack.isEmpty() << endl;
cout << stack.GetTop() << endl;
cout << "Pop : " << stack.Pop() << endl;
cout << "Pop : " << stack.Pop() << endl;
cout << stack.GetTop() << endl;
return 0;
}
下面是控制台中的输出。
三、总结和心得
实现顺序栈的时候比较轻松,因为数组还是挺好操作的,毕竟用了好久的数组了,加上平时开发中也很少遇到指针,除了调用一些API的必要时候需要一个指针。但是在实现链栈的时候遇到了困难,在链栈的设计上还是参考了书本上的设计。当然了,好的程序的都是改出来的,上面的代码必须不是最好的。写模板也是为了日后修改,让自己写的模板越写越好,从修改中进步。
在栈的从学习中,必须要记住,栈是先进后出的,当然这个也贯穿了上面的代码。
在空闲的时候更新的地方,大家可以捧一下场,嘿嘿~
新世界的大门 (๑•̀ㅂ•́)و✧