栈的介绍及使用【c++】

 今天,本尊给你们介绍一下栈!

栈的数据结构定义

栈是一种线性的数据结构,遵循 后进先出(LIFO, Last In First Out) 的原则。这意味着最后被压入栈中的元素会最先弹出。栈的操作通常包括 push(入栈)、pop(出栈)以及查看栈顶元素的 top 或者 peek

通过两种主要方式可以实现栈:基于数组的方式和基于链表的方式。


基于数组的栈实现

以下是基于数组的栈的具体实现方法:

typedef int STDataType;

// 定义栈结构
typedef struct stack {
    STDataType* a;       // 指向存储数据的动态数组
    int top;             // 当前栈顶位置索引
    int capacity;        // 栈的最大容量
} ST;

上述代码片段中,a 是一个指向动态分配内存区域的指针,用于保存栈内的数据;top 表示当前栈顶的位置索引;capacity 则表示该栈能够容纳的最大元素数量1

初始化函数

初始化栈时需要为其分配初始容量并设置默认参数:

void StackInit(ST* pst) {
    assert(pst);
    pst->a = malloc(sizeof(STDataType) * 4);     // 默认分配4个单位的空间
    if (pst->a == NULL) exit(-1);               // 如果分配失败则退出程序
    pst->top = 0;                               // 栈为空时,top=0
    pst->capacity = 4;                          // 设置初始容量为4
}

此部分实现了栈对象的初始化操作,其中使用了 malloc() 函数来动态申请内存空间,并设置了栈的初始状态。

动态扩容机制

当栈满时需扩展其容量以便继续存入新元素:

void StackExpand(ST* pst) {
    assert(pst);

    // 创建新的更大的连续内存块
    STDataType* tmp = realloc(pst->a, sizeof(STDataType) * pst->capacity * 2);
    if (tmp == NULL) exit(-1);                  // 扩展失败处理
    
    pst->a = tmp;                              // 更新原地址至扩增后的内存区
    pst->capacity *= 2;                        // 叠加两倍原有容量作为新的总容量
}

这里展示了如何利用 C 库函数 realloc() 对已有堆上分配的对象进行尺寸调整的过程。

入栈与出栈功能

分别提供两个接口完成基本的功能需求:

Push(入栈)

将指定数值加入到栈顶端:

void StackPush(ST* pst, STDataType x){
    if (pst->top == pst->capacity){            // 若已达到上限,则触发自动增长逻辑
        StackExpand(pst);
    }
    
    pst->a[pst->top++] = x;                   // 将传入值赋给对应下标的单元格后再自增计数器
}
Pop(出栈)

移除位于顶部的那个项目并将它返回给调用方:

STDataType StackPop(ST* pst){
    assert(pst && pst->top > 0);              // 验证合法性前提条件成立与否

    return pst->a[--pst->top];                // 自减计数器之后读取旧版最高层记录的内容
}

基于链表的栈实现

另一种常见的做法是以单项链表的形式构建栈模型。下面给出具体实例说明:

节点类型声明
#include <stdio.h>
#include <stdlib.h>

typedef int data_t;

// 单项节点定义
typedef struct node{
    data_t data;          // 存储实际信息字段
    struct node *next;   // 下一结点链接指示符
} listnode,*linkstack;

此处我们重新设计了一个简单的单项列表节点形式,准备用来搭建我们的目标容器体系2.

构造空栈过程
linkstack sqtack_create(void){
    linkstack sq;
    sq=(linkstack )malloc(sizeof(listnode));
    if(!sq){
        printf("Memory allocation failure!\n");
        return NULL;
    }

    sq->data=0;         // 记录长度初设为零
    sq->next=NULL;      // 清理后续连接关系标志位
    return sq;
}

这段源码负责开辟一块固定大小的新区块供作头哨兵角色之用途,同时将其内部属性置成合理初识形态.

插入动作执行流程

每当有新增请求到达时,就依照既定规则把待加工材料挂载上去即可满足业务诉求。

int push(linkstack s,data_t val){
    linkstack new_node=(linkstack)calloc(1,sizeof(*new_node));

    if(new_node==NULL)return -1;

    new_node->data=val;
    new_node->next=s->next;
    s->next=new_node;
    ++s->data;
    return 0;
}

同理可得删除环节亦然简单明了很多呢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

泪光2929

加油!!!

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

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

打赏作者

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

抵扣说明:

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

余额充值