linux学习:栈

目录

顺序栈

结构

初始化一个空顺序栈

压栈

出栈

例子 十进制转八进制

链式栈

管理结构体的定义

初始化

压栈

出栈


顺序栈

顺序栈的实现,主要就是定义一块连续的内存来存放这些栈元素,同时为了方便管理, 再定义一个整数变量来代表当前栈顶元素在此连续内存中的偏移量,这样就可以很方便地知 道栈的状态和当前栈顶元素的位置,便于压栈和出栈操作。将栈内存地址和栈顶元素偏移量 放在一起,形成一个专门用来管理顺序栈的结构体,我们称之为管理结构体

结构

struct sequent_stack // 栈的管理结构体
{
    int *stack; // 用 stack 指向一块连续的内存来存储栈元素
    int size; // size 保存了该顺序栈的总大小
    int top; // 用 top 来指示栈顶元素的偏移量
};

初始化一个空顺序栈

一个空栈意味着栈中 没有元素,首先将 stack 指向的内存清零,其次更重要的是将 top 置为-1,同时规定-1 为 空栈的标志,这么做的好处是:将来压栈第一个元素之后,立即将 top 加 1 就会得到 0, 而第一个元素就放在 stack 所指向的内存的开端处,偏移量刚好为 0

struct sequent_stack *init_stack(int size) // 参数 size 表明空栈的初始大小
{
    struct sequent_stack *s;
    s = malloc(sizeof(struct seqent_stack)); // 申请栈管理结构体
    if(s != NULL)
    {
        s->stack = calloc(size, sizeof(int)); // 申请栈空间,并由 stack 指向
        s->size = size;
        s->top = -1; // 将栈顶偏移量置为-1,代表空栈
    }
    return s;
}

压栈

假设栈中已有一些元素,压栈的第一步首先要判 断栈是否已满,如果已满就要考虑扩充栈空间或者直接出错返回,如果未满,则需要将新的 栈顶元素堆叠到原栈顶之上

bool stack_full(struct sequent_stack *s)
{
    return s->top >= s->size-1; // 判断栈是否已满
}
bool push(struct sequent_stack *s, int data)
{
    if(stack_full(s)) // 如果栈已满,则出错返回
        return false;
    s->top++;
    s->stack[s->top] = data;
    return true;
}

出栈

出栈之前,需要判断栈是否为空

bool stack_empty(struct sequent_stack *s)
{
    return s->top == -1; // 判断栈是否为空
}
bool pop(struct sequent_stack *s, int *p) // p 指向存放栈顶元素的内存
{
    if(stack_empty(s)) // 如果栈为空,则出错返回
        return false;
    *p = s->stack[s->top];
    s->top--;
    return true;
}

例子 十进制转八进制

int main(void)
{
    struct sequent_stack *s;
    s = init_stack(10); // 初始化一个具有 10 个元素空间的顺序栈
    int n;
    scanf("%d", &n); // 让用户输入一个需要转换的十进制数
    while(n > 0)
    {
        push(s, n%8); // 使用短除法将余数统统压栈
        n /= 8;
    }
    int m;
    while(!stack_empty(s)) // 只要栈不为空,就继续循环
    {
        pop(s, &m); // 出栈并打印出来
        printf("%d", m);
    }
    printf("\n");
    return 0;
}

链式栈

对于链式栈而言,同样也需要一系列基本操作:初始化、压栈、出栈、判断是否为空、 判断是否已满等等。首先,初始化一个空栈,意味着使得 top 指向 NULL,而 size 记为 0

管理结构体的定义

struct node // 栈节点结构体
{
    int data;
    struct node *next;
};
struct linked_stack // 栈管理结构体
{
    struct node *top;
    int size;
};

初始化

struct linked_stack *init_stack(void)
{
    struct linked_stack *s;
    s = malloc(sizeof(struct linked_stack)); // 申请一个管理结构体
    if(s != NULL)
    {
        s->top = NULL; // j 将栈置空
        s->size = 0;
    }
    return s;
}

压栈

压栈首先需要一个新节点,然后 将新的节点的 next 指针指向原来的栈顶,再让 top 指针指向该新的栈顶元素即可

创建新结点

struct node *new_node(int data) // 创建一个新的节点
{
    struct node *new;
    new = malloc(sizeof(struct node));
    if(new != NULL)
    {
        new->data = data;
        new->next = NULL;
    }
    return new;
}

将新节点 new 压栈

bool push(struct linked_stack *s, struct node *new) // 将新节点 new 压栈
{
    if(s == NULL || new == NULL)
        return false;
    new->next = s->top; // 第①步(见上图)
    s->top = new; // 第②步
    s->size++;
    return true;
}

出栈

对于出栈来说,首先要判断栈是否为空,如果不为空,则先要用一个指针 tmp 来保存 原栈顶元素的地址,然后返回栈顶元素,再将 top 指针指向下一个元素,最后要注意释放 tmp 所指向的原栈顶元素的内存空间

bool pop(struct linked_stack *s, int *p)
{
    if(s == NULL || p == NULL || stack_empty(s))
        return false;
    struct node *tmp = s->top; // 第①步
    *p = tmp->data; // 第②步
    s->top = s->top->next; // 第③步
    free(tmp); // 第④步
    s->size--;
    return true;
}

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值