栈的实现(双向循环链式存储结构+顺序存储结构+STL类模板)

栈的实现(双向循环链式存储结构+顺序存储结构+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、对堆栈进行操作时,一定要记得查看堆栈是否为空
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值