《数据结构》-顺序栈的表示和实现

 基本概念

栈的顺序存储结构称为顺序栈

使用数组作为顺序栈存储方式的特点:简单方便单容易产生溢出(数组大小固定)

  • 上溢:栈已经满,还要压入元素
  • 下溢:栈已经空,还要弹出元素

上溢一般认为是一种错误,使问题的处理无法进行,而下溢一般认为是一种结束条件,即问题处理结束。

栈顶指针

top 栈顶指针,指示栈顶元素在顺序栈中的位置。但是一般为了方便,通常 top 指向栈顶元素之上的下标位置。

栈底指针

base 栈底指针,指示栈底元素在顺序栈中的位置,在栈构造之前和销毁之后,base 的值为 NULL

栈空

base 栈底指针 = top 栈顶指针

入栈

代码实现

#include <string.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>

// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1

typedef int Status;    // Status 是函数的类型,其值是函数结果状态代码,如 OK 等
typedef int Boolean;   // Boolean 是布尔类型,其值是 TRUE 或 FALSE
typedef int SElemType; // 定义栈元素类型为整型

#define STACK_INIT_SIZE 10 // 存储空间初始分配量
#define STACK_INCREMENT 2  // 存储空间分配增量

typedef struct SqStack
{
    SElemType *top;  // top 栈顶指针,指示栈顶元素在顺序栈中的位置。但是一般为了方便,通常 top 指向栈顶元素之上的下标位置。
    SElemType *base; // base 栈底指针,指示栈底元素在顺序栈中的位置,在栈构造之前和销毁之后,base 的值为 NULL
    int stacksize;   // 当前已分配的存储空间,以元素为单位
} SqStack;           // 定义一个顺序栈数据类型

// 顺序栈的基本操作(9个)

/* 初始化操作 */
void InitStack(SqStack *S)
{ // 操作结果:构造一个空栈 S
    S->base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType));
    if (!(S->base))
        exit(-1); // 存储分配失败
    S->top = S->base;
    S->stacksize = STACK_INIT_SIZE;

    return;
}

/* 销毁栈操作 */
void DestroyStack(SqStack *S)
{ // 初始条件:栈 S 已经存在
    // 操作结果:销毁栈 S,S 不再存在
    free(S->base);
    S->base = NULL;
    S->top = NULL;
    S->stacksize = 0;

    return;
}

/* 栈置空操作 */
void ClearStack(SqStack *S)
{ // 初始条件:
    // 操作结果:把 S 置为空栈
    if (S->base)
        S->top = S->base;

    return;
}

/* 判断 S 是否为空 
空栈:base == top 是栈空标志
*/
Status StackEmpty(SqStack S)
{ // 初始条件:栈 S 已经存在
    // 操作结果:若栈 S 为空栈,则返回 TRUE,否则返回 FALSE
    if (S.top == S.base)
        return TRUE;
    else
        return FALSE;
}

/* 求栈的长度 */
int StackLength(SqStack S)
{ // 初始条件:栈 S 已经存在
    // 操作结果:返回 S 的元素个数,即栈的长度
    return S.top - S.base;
}

/* 获取栈顶元素 */
Status GetTop(SqStack S, SElemType *e)
{ // 初始条件:栈 S 已经存在
    // 操作结果: 若栈不空,则用 e 返回 S 的栈顶元素,并返回 OK;否则返回 ERROR
    if (S.top > S.base)
    {
        *e = *(S.top - 1);
        return OK;
    }
    else
    {
        return ERROR;
    }
}

/* 入栈操作 
栈满:top - base == stacksize
算法思路:
1、判断是否满栈
2、元素 e 压入栈顶元素
3、栈顶指针加 1
*/
void Push(SqStack *S, SElemType e)
{ // 初始条件:栈 S 已经存在
    // 操作结果:插入元素 e 为新的栈顶元素
    if (S->top - S->base >= S->stacksize) // 栈满,追加存储空间
    {
        S->base = (SElemType *)realloc(S->base, (S->stacksize + STACK_INCREMENT) * sizeof(SElemType));
        if (!(S->base))
            exit(-1); // 存储分配失败
        S->top = S->base + S->stacksize;
        S->stacksize += STACK_INCREMENT;
    }
    *(S->top)++ = e;
}

/* 出栈操作 
栈空:top == base 下溢
算法思路:
1、判断是否栈空
2、栈顶指针减 1
3、获取栈定元素
*/
Status Pop(SqStack *S, SElemType *e)
{ // 初始条件:栈 S 已经存在
    // 操作结果: 若栈不空,则删除 S 的栈顶元素,用 e 返回其值,并返回 OK;否则返回 ERROR
    if (S->top == S->base)
        return ERROR;
    *e = *--(S->top);
    return OK;
}

/* 遍历栈 */
void StackTraverse(SqStack S, void (*visit)(SElemType))
{ // 初始条件:栈 S 已经存在
    // 操作结果:从栈底到栈顶依次对栈中每个元素调用函数 visit()
    while (S.top > S.base)
        visit(*S.base++);
    printf("\n");
}

void main(int argc, char *argv[])
{
    int j;
    SqStack s;
    SElemType e;
    InitStack(&s);           // 初始化栈s
    for (j = 1; j <= 5; j++) // 将2,4,6,8,10入栈
        Push(&s, 2 * j);
    Pop(&s, &e);
    printf("pop stack is %d\n", e);
    GetTop(s, &e);
    printf("top value is %d\n", e);

    Pop(&s, &e);
    printf("pop stack is %d\n", e);
    GetTop(s, &e);
    printf("top value is %d\n", e);
}

/*
编译:gcc test.c -o test
运行:./test
结果:
pop stack is 10
top value is 8
pop stack is 8
top value is 6
*/

/********************* end of file ******************************/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
顺序栈是一种基于数组实现的栈,它的特点是具有随机存取的特性。顺序栈的基本运算包括进栈、出栈和查看栈顶元素。进栈操作将元素插入到栈顶,出栈操作将栈顶元素删除并返回,查看栈顶元素操作返回栈顶的元素值,但不修改栈的状态。 在C语言中,顺序栈的存储结构可以使用一个一维数组来存放栈中的元素,同时使用一个指示器top来指示栈顶的位置。在进行进栈和出栈操作时,需要更新top的值,使其指向栈顶元素。 下面是一种常见的顺序栈的定义和基本操作的示例代码: ```c // 定义栈中元素的数据类型 typedef int StackElementType; // 定义顺序栈的存储结构 #define Stack_Size 100 // 栈的最大容量 typedef struct { StackElementType elem[Stack_Size]; // 用数组存放栈中元素 int top; // 栈顶指针 } SeqStack; // 初始化顺序栈 void Init_SeqStack(SeqStack *S) { S->top = -1; // 初始时栈为空,栈顶指针置为-1 } // 进栈操作 void Push_SeqStack(SeqStack *S, StackElementType x) { if (S->top == Stack_Size - 1) { printf("栈已满,无法进栈"); return; } S->top++; // 栈顶指针加1 S->elem[S->top] = x; // 将新元素放入栈顶位置 } // 出栈操作 StackElementType Pop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("栈为空,无法出栈"); return -1; // 返回一个特殊值表示出错 } StackElementType x = S->elem[S->top]; // 获取栈顶元素的值 S->top--; // 栈顶指针减1 return x; // 返回栈顶元素的值 } // 查看栈顶元素 StackElementType GetTop_SeqStack(SeqStack *S) { if (S->top == -1) { printf("栈为空"); return -1; // 返回一个特殊值表示出错 } return S->elem[S->top]; // 返回栈顶元素的值 } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值