栈(顺序栈,链栈)

版权声明:Andy https://blog.csdn.net/Alibaba_lhl/article/details/82857359

顺序栈

顺序栈是指利用顺序存储结构实现的栈,即利用一组地址连续的存储单元依次存放自栈底到栈顶的数据元素。

代码实现如下:

#include <iostream>
#include <stdio.h>
#include <malloc.h>
using namespace std;

typedef int SElemType;
typedef int Status;
#define INIT_SIZE 100
#define STACKINCREMENT 10
#define Ok 1
#define Error 0
#define True 1
#define False 0
typedef struct
{
    SElemType *base;///栈底指针
    SElemType *top;///栈顶指针
    int stacksize;///栈可用的最大容量
}SqStack;

Status InitStack(SqStack *s)///初始化栈
{
    s->base = (SElemType *)malloc(INIT_SIZE * sizeof(SElemType));///将顺序栈动态分配一个最大容量为INIT_SIZE的数组空间
    if(!s->base)///存储分配失败
    {
        puts("存储空间分配失败!");
        return Error;
    }
    s->top = s->base;///top初始为base,空栈
    s->stacksize = INIT_SIZE;///stacksize置为栈的最大容量为INIT_SIZE
    return Ok;
}
///if(base==NULL) 栈结构不存在
///栈非空时,top指向栈顶元素的上一位置

Status Push(SqStack *s, SElemType e)///压栈(插入元素e为新的栈顶元素)
{
    if(s->top - s->base >= s->stacksize)///栈满
    {
        s->base = (SElemType *)realloc(s->base, (s->stacksize + STACKINCREMENT) * sizeof(SElemType));///改变栈的内存大小
        if(!s->base)
        {
          puts("存储空间分配失败!");
          return Error;
        }
        s->top = s->base + s->stacksize;///修改栈顶位置
        s->stacksize += STACKINCREMENT;///修改栈长度
    }
    *s->top++ = e;
    return Ok;
}

Status Pop(SqStack *s, SElemType *e)///弹栈
{///删除栈顶元素,用e返回其值
    if(s->top == s->base) return Error;///栈空时,无法进行操作
    --s->top;///栈顶指针减1
    *e = *(s->top);///将栈顶元素赋给e
    return Ok;
}

Status GetTop(SqStack *s, SElemType &e)///获得栈顶元素
{
  if(s->top == s->base) return Error;///栈底指针和栈顶指针相同时,栈为空
  e = *(s->top - 1);///栈非空时,top始终指向栈顶元素的上一个位置
  return Ok;
}

Status visit(SElemType c)
{
    printf("%d ",c);
    return Ok;
}
Status StackTraverse(SqStack *s,Status(*visit)(SElemType))///遍历栈
{
    SElemType *b = s->base;///此处不能直接用base或top移动,即不能改变原栈的结构
    SElemType *t = s->top;
    while(t > b)
    {
        visit(*b++);
    }
    printf("\n");
    return Ok;
}

Status ClearStack(SqStack *s)///清空栈
{
    s->top = s->base;
    return Ok;
}

Status StackEmpty(SqStack *s)///栈是否为空
{
    if(s->top == s->base) return True;///栈底指针和栈顶指针相同时,栈为空
    else  return False;
}

Status Destroy(SqStack *s)///销毁栈
{
    free(s->base);
    s->base = NULL;
    s->top = NULL;
    s->stacksize = 0;
    return Ok;
}

int main()
{
    cout<< "1. 进栈" << endl;
    cout<< "2. 出栈" << endl;
    cout<< "3. 取栈顶元素" << endl;
    cout<< "4. 遍历栈" << endl;
    cout<< "0. 退出" << endl << endl;
    SqStack a;///定义一个栈,命名为a
    SqStack *s = &a;///s为栈的指针
    SElemType e;
    InitStack(s);
    int n;
    puts("请输入要进栈的个数:");
    scanf("%d", &n);
    while(n--)
    {
        int m;
        scanf("%d", &m);
        Push(s, m);
    }
    int choose = -1;
    while(choose != 0)
    {
        cout<< "请选择:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                cin>> e;
                Push(s,e);
            }
            break;
            case 2:
            {
                if(StackEmpty(s))
                {
                    printf("该栈以空,无法进行该操作\n");
                    return 0;
                }
                Pop(s, &e);
                printf("出栈的元素是:%d\n", e);
                printf("元素出栈后事实上并没有清除,依然存在于内存空间,所谓的出栈只是指针移动,出栈的元素是%d\n\n", *s->top);
                //判断出栈后元素是否还存在于内存中
            }
            break;
            case 3:
            {
                if(StackEmpty(s))
                {
                    printf("该栈以空,无法进行该操作\n");
                    return 0;
                }
                GetTop(s, e);
                printf("栈顶元素为:%d\n\n",e);
            }
            break;
            case 4:
            {
                StackTraverse(s, visit);///遍历该栈
                puts("");
            }
            break;
        }
    }
    Destroy(s);
    return 0;
}

程序运行: 

链栈

链栈是指采用链式存储结构实现的栈,通常用单链表来表示。

代码实现如下:

#include <bits/stdc++.h>
using namespace std;
#define OK 1
#define ERROR 0
typedef long long ll;
typedef unsigned long long ull;
typedef int SElemType;
typedef int Status;
typedef struct StackNode///链栈的存储结构
{
    SElemType data;
    struct StackNode *next;
}StackNode, *LinkStack;

Status InitStack(LinkStack &S)///链栈的初始化
{///构建一个空栈S,栈顶指针置空
    S = NULL;///链栈的初始化操作就是构造一个空栈,因为没必要设头结点,所以直接将栈顶指针置空。
    return OK;
}
Status Push(LinkStack &S, SElemType e)
{///在栈顶插入元素(将元素插入到首元结点)
    LinkStack p;
    p = new StackNode; ///生成新结点
    p->data = e;       ///将新结点指针插入栈顶
    p->next = S;       ///将新结点数据域插入栈顶
    S = p;             ///修改栈顶指针为p
    return OK;
}
Status Pop(LinkStack &S, SElemType &e)
{///删除栈顶元素,用e返回其值
    LinkStack p;
    if(S==NULL) return ERROR;///栈空
    e = S->data;    ///将栈顶元素赋给e
    p = S;          ///用p临时保存栈顶元素空间
    S = S->next;    ///修改栈顶指针
    delete p;       ///释放原栈顶元素的空间
    return OK;
}
Status GetTop(LinkStack S, SElemType &e)///取栈顶元素
{
    if(S==NULL) return ERROR;///栈空
    e = S->data;
    return OK;
}
Status StackTraverse(LinkStack S)
{
    LinkStack p;
    if(S==NULL) return ERROR;
    p = S;
    while(p)
    {
        cout<< p->data << " ";
        p = p->next;
    }
    cout<< endl;
    return OK;
}
int main()
{
    cout<< "1. 进栈" << endl;
    cout<< "2. 出栈" << endl;
    cout<< "3. 取栈顶元素" << endl;
    cout<< "4. 遍历栈" << endl;
    cout<< "0. 退出" << endl << endl;
    LinkStack S;///定义一个栈,命名为a
    SElemType e;
    InitStack(S);
    int n, m;
    puts("请输入要进栈的个数:");
    scanf("%d", &n);
    while(n--)
    {
        int m;
        scanf("%d", &m);
        Push(S, m);
    }
    int choose = -1;
    while(choose != 0)
    {
        cout<< "请选择:";
        cin>> choose;
        switch(choose)
        {
            case 1:
            {
                cin>> e;
                Push(S,e);
            }
            break;
            case 2:
            {
                if(S==NULL)
                {
                    printf("该栈以空,无法进行该操作\n");
                    return 0;
                }
                Pop(S,e);
                printf("出栈的元素是:%d\n", e);
                printf("元素出栈后已经释放空间,出栈的元素是%d\n\n", e);
            }
            break;
            case 3:
            {
                if(S==NULL)
                {
                    printf("该栈以空,无法进行该操作\n");
                    return 0;
                }
                GetTop(S, e);
                printf("栈顶元素为:%d\n\n",e);
            }
            break;
            case 4:
            {
                StackTraverse(S);///遍历该栈
                puts("");
            }
            break;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Alibaba_lhl/article/details/82857359