3.2.1【顺序栈】

141 阅读2分钟

1. 概念

顺序栈,即操作受限的顺序表。

逻辑结构:线性结构

物理结构:顺序存储结构

栈的特点:后进先出

2. 接口实现

2.1. 注意:

  • 通常用 top = -1 代表,栈空

2.2. 定义 操作顺序栈 的结构体

typedef int SSDataType;
typedef struct SeqStack
{
    SSDataType *data; // 指向 栈 的存储位置
    int maxlen;       // 保存 栈 的 最大 长度
    int top;          // top始终代表 当前栈内最后一个有效元素 的下标(在心里当成last用)
} SS;
  • data:存放用malloc所开辟空间 的的首地址;
    • 而不是整个数组,这样结构体占用的空间就会变小。
  • maxlen:用maxlenmalloc指定长度的 顺序地址长度空间,即堆区的数组。

2.3. 创建空的顺序栈

2.4. 入栈

2.5. 出栈

2.6. 栈长度(存在几个有效数据)

2.7. 获取栈顶数据

2.8. 清空顺序(操作栈针即可)

不允许用户访问

3. 总的代码

#include <stdio.h>
#include <stdlib.h>
#define DEBUG(Str) printf("%s %s %s %d\n", Str, __func__, __FILE__, __LINE__)

// 定义 操作顺序栈 的结构体
typedef int SSDataType;
typedef struct SeqStack
{
    SSDataType *data; // 指向 栈 的存储位置
    int maxlen;       // 保存 栈 的 最大 长度
    int top;          // top始终代表 当前栈内最后一个有效元素 的下标(在心里当成last用)
} SS;

// 创建一个 操作顺序栈的结构体,并在其中 申请顺序表空间
SS *SSInit(int len)
{
    // 申请 存放 操作顺序栈 的结构体空间
    SS *PS = (SS *)malloc(sizeof(SS));
    if (NULL == PS)
    {
        DEBUG("SSInit err, operate struct malloc err");
        return NULL;
    }

    // 初始化 操作顺序栈的结构体 成员
    PS->maxlen = len; //传入的 长度
    PS->top = -1;     //-1 代表空栈

    // 同时申请 新的 顺序表空间
    PS->data = (SSDataType *)malloc(sizeof(SSDataType) * len);
    if (NULL == PS->data)
    {
        DEBUG("data malloc err");
        return NULL;
    }

    // 返回,操作顺序栈 的结构体
    return PS;
}

// 入栈
int SSPush(SS *PS, SSDataType data)
{
    // 容错判断,满没满
    if (PS->top + 1 == PS->maxlen)
    {
        DEBUG("SSPush failed, FULL");
        return -1;
    }

    // 入栈
    // 先栈针上移,然后数据入栈
    // -> 优先于 ++
    PS->data[++PS->top] = data;

    return 0;
}

// 出栈
SSDataType SSPop(SS *PS)
{
    // 如果 空栈,没法出
    if (PS->top < 0)
    {
        DEBUG("Empty, can't Pop");
        return (SSDataType)(-1); //看情况改动
    }

    // 出栈
    // 先 栈针下移,然后出数据
    // 这种写法安全
    PS->top--;
    return PS->data[PS->top + 1];
}

// 栈长度(存在几个有效数据)
int SSLength(SS *PS)
{
    // 栈针 总比 长度 小1
    return PS->top + 1;
}

// 获取栈顶数据
SSDataType SSGetTop(SS *PS)
{
    // 栈针小于0,是空栈
    if (PS->top < 0)
    {
        printf("SS is empty.\n");
        return (SSDataType)(-1);
    }
    else
        return PS->data[PS->top];
}

// 清空顺序(操作栈针即可)
void SSClear(SS *PS)
{
    PS->top = -1;
}

int main(int argc, char *argv[])
{
    // 初始化 顺序栈 和 操作顺序栈的 结构体
    SS *PS = SSInit(10);

    // 入栈
    for (int i = 1; i <= 6; i++)
        SSPush(PS, i * 11);

    //  出栈
    printf("Pop :%d\n", SSPop(PS));

    // 求栈长
    printf("SSLength is %d\n", SSLength(PS));

    SSPush(PS, 11);
    SSPush(PS, 21);

    // 求栈长
    printf("SSLength is %d\n", SSLength(PS));

    // 6. 获取栈顶数据
    printf("SSTop is %d\n", SSGetTop(PS));

    // 7. 清空顺序栈,让用户无法访问到
    SSClear(PS);

    // 完全使用完记得销毁空间且指向NULL避免野指针
    free(PS->data);
    PS->data = NULL;

    // data 和 ps 都是malloc而来的
    free(PS);
    PS = NULL;

    return 0;
}