栈的实现(双向循环链式存储结构+顺序存储结构+STL类模板)
栈
1.顺序存储结构
// 栈(顺序存储结构)C++.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
//Status是状态码,标识着函数执行结果的状态,OK或者ERROR
typedef int Status;
class SqStack {
private:
int MaxSize; //数组最大长度
int top; //栈顶指针,表示栈顶的索引,所以top=-1时为空表
ElemType* list; //指向数组的指针
public:
SqStack();
~SqStack();
Status Push(ElemType e); //将元素e推进栈
Status Pop(ElemType *e); //栈顶元素出栈,且记录出栈元素
Status Pop(); //栈顶元素出栈
Status GetTop(ElemType* e); //获取栈顶元素
void ClearStack(); //清空栈内元素
void display(); //打印所有栈内元素,从索引0开始顺序打印
};
SqStack::SqStack() { //初始化
top = -1;
MaxSize = 99; //默认最大长度为99
list = new int[MaxSize];
}
SqStack::~SqStack() {
delete[]list;
}
Status SqStack::Push(ElemType e) {
if (top == MaxSize - 1) //栈满
return ERROR;
top++;
list[top] = e;
return OK;
}
Status SqStack::Pop(ElemType *e) {
if (top == -1) //栈空
return ERROR;
*e = list[top];
top--;
return OK;
}
Status SqStack::Pop() {
if (top == -1) //栈空
return ERROR;
top--;
return OK;
}
Status SqStack::GetTop(ElemType* e) {
if (top == -1)
return ERROR;
*e = list[top];
return OK;
}
void SqStack::ClearStack() {
top = -1; //这里不需要释放空间,直接top置为-1即可
}
void SqStack::display() {
if (top == -1)
cout << "当前为空栈!!!" << endl;
else
{
cout << "当前栈内元素有:";
for (int i = 0; i < top + 1; i++)
{
cout << list[i] << " ";
}
cout << endl;
}
}
int main()
{
SqStack test;
test.Push(1);
test.display();
test.Push(2);
test.display();
test.Push(3);
test.display();
test.Pop();
test.display();
ElemType *topElem;
topElem = new ElemType;
test.GetTop(topElem);
cout << "栈顶元素为:" << *topElem << endl;
test.ClearStack();
test.display();
return 0;
}
2.双向循环链式存储结构
// 栈(顺序存储结构)C++.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
#include <iostream>
#include<stdio.h>
using namespace std;
typedef int ElemType;
#define OK 1
#define ERROR 0
//Status是状态码,标识着函数执行结果的状态,OK或者ERROR
typedef int Status;
//单链表结点类
class Node {
public:
ElemType data; //节点数据
Node* next; //指向下一节点指针
Node* front; //指向上一节点指针
Node() { //构造函数初始化栈顶节点******单链表用头结点表示整个链表,现在不同,是用栈顶指针来表示整个链表(其实意思就是第一个位置是栈顶)
next = NULL;
front = NULL;
data = 0;
}
};
class LinkStack {
private:
Node* top; //栈顶节点指针
Node* bottom; //栈底节点指针
int len; //链表长度
public:
LinkStack();
~LinkStack();
Status Push(ElemType e); //将元素e推进栈
Status Pop(ElemType* e); //栈顶元素出栈,且记录出栈元素
Status Pop(); //栈顶元素出栈
Status StackEmpty(); //判断是否为空栈(1:是 0:不是)
Status GetTop(ElemType* e); //获取栈顶元素
Status ClearStack(); //清空栈内元素
void display(); //打印所有栈内元素,从索引0开始顺序打印
};
LinkStack::LinkStack() { //初始化
top = new Node;
len = 0;
}
LinkStack::~LinkStack() {
Node* p, * q;
p = top; //p指向第一个节点
for (int i = 0; i < len; i++)
{
q = p->next;
delete p;
p = q;
}
len = 0;
}
Status LinkStack::StackEmpty() {
if (len == 0)
return 1;
else
return 0;
}
Status LinkStack::Push(ElemType e) {
Node* temp;
temp = new Node;
temp->data = e;
temp->next = top; //把当前第一个元素节点指针(栈顶指针)赋值在插入的新节点的后继
top->front = temp; //把插入的新节点赋值给原本栈顶节点的前继
top = temp; //将新节点赋值给栈顶指针
if (len == 0) { //len=0即推进第一个节点的时候才需要记录bottom(因为bottom不会变),这时top的前继节点还是top本身
top->front = top;
bottom = top;
}
else
top->front = bottom;
len++;
return OK;
}
Status LinkStack::Pop(ElemType* e) {
if (StackEmpty()) //栈空
return ERROR;
*e = top->data;
Node* temp;
temp = top;
top->front->next = top->next;
top->next->front = top->front;
top = temp->next;
delete temp;
len--;
return OK;
}
Status LinkStack::Pop() {
if (StackEmpty()) //栈空
return ERROR;
Node* temp;
temp = top;
top->front->next = top->next;
top->next->front = top->front;
top = temp->next;
delete temp;
len--;
return OK;
}
Status LinkStack::GetTop(ElemType* e) {
if (StackEmpty()) //栈空
return ERROR;
*e = top->data;
return OK;
}
Status LinkStack::ClearStack() {
Node* p, * q;
p = top->next; //p指向第二个节点
for (int i = 0; i < len-1; i++)
{
q = p->next;
delete p;
p = q;
}
//top = NULL; //栈顶指针域设为空(×)
top->next = NULL; //表示链表的指针不能置空或者delete,所以上一行代码是错误的,应该清空栈是回到一开始构造的状态,不是删除指针,否注栈就消失了
top->front = NULL;
len = 0;
return OK;
}
void LinkStack::display() {
Node *temp;
if (StackEmpty())
cout << "当前为空栈!!!" << endl;
else
{
temp = top;
cout << "当前栈内元素有:";
for (int i = 0; i < len; i++)
{
cout << temp->front->data << " ";
temp = temp->front;
}
cout << endl;
}
}
int main()
{
LinkStack test;
test.Push(1);
test.display();
test.Push(2);
test.display();
test.Push(3);
test.display();
test.Pop();
test.display();
ElemType* topElem;
topElem = new ElemType;
test.GetTop(topElem);
cout << "栈顶元素为:" << *topElem << endl;
test.ClearStack();
test.display();
test.Push(1);
test.display();
test.ClearStack();
test.display();
return 0;
}
3.STL类模板实现
stack类使用的参考代码
- 1、包含头文件:
#include <stack>
- 2、创建一个堆栈对象s(注意stack是模板类):stack s; //堆栈的数据类型是字符型
- 3、把一个字符ct压入堆栈:
s.push(ct)
; - 4、把栈顶元素弹出:
s.pop()
; - 5、获取栈顶元素,放入变量c2: c2 =
s.top()
; - 6、判断堆栈是否空:
s.empty()
,如果为空则函数返回true,如果不空则返回false - 7、对堆栈进行操作时,一定要记得查看堆栈是否为空