堆栈

基本特征:后进先出(LIFO)

基本操作:压入(push),弹出(pop)

实现要点:初始化内存空间,栈顶指针,判空判满

缺点:容易造成空间浪费,且易受初始化空间的局限

一般而言,栈的重要程度要大于队列,栈的用途非常广泛,除了表达式求值,在深度优先遍历、保存现场等问题中经常出现。,

举例1:基于数组的堆栈

//堆栈
typedef struct ZHLStack{
    int *array;
    size_t cap;//容量
    size_t top;//栈顶
    
}ZHLSTACK;

//分配内存,并初始化为空堆栈
void stackInit(ZHLSTACK *stack,size_t cap){
    stack->array = (int *)malloc(cap * sizeof(int));
    stack->cap = cap;
    stack->top = 0;
    
}
//释放内存并恢复到初始状态
void stackDelete(ZHLSTACK *stack){
    free(stack->array);
    stack->array = NULL;
    stack->cap = 0;
    stack->top = 0;
}
//判断堆栈是否满
int stackFull(ZHLSTACK *stack){
    return stack->top >= stack->cap;
}
//判断堆栈是否为空
//top为零
int stackEmpty(ZHLSTACK *stack){
    return !stack->top;
}
//push
void stackPush(ZHLSTACK *stack,int data){
    stack->array[stack->top ++] = data;
}
//pop
int stackPop(ZHLSTACK *stack){
    return stack->array[-- stack->top];
}
//获取容量
size_t stackSize(ZHLSTACK *stack){
    return stack->top;
}
//获取栈顶元素
int stackTop(ZHLSTACK *stack){
    return stack->array[stack->top - 1];
}

int main() {
    ZHLSTACK stack;
    stackInit(&stack, 6);
    int i = 0;
    while (!stackFull(&stack)) {
        stackPush(&stack, i ++);
    }
    printf("size = %zu\r\n",stackSize(&stack));
    while (! stackEmpty(&stack)) {
        printf("%d\r\n",stackPop(&stack));
    }
    stackDelete(&stack);
    return 0;
}

举例2:基于链表的堆栈

//节点
typedef struct stackListNode{
    int data;//value
    struct stackListNode *next;//后指针
} SLNode;
//堆栈
typedef struct MyStack{
    SLNode *top;//栈顶
} MYStack;
//创建节点
static SLNode* createNode(SLNode *next,int val){
    SLNode *node = malloc(sizeof(SLNode));
    node->data = val;
    node->next = next;
    return node;
}
//销毁节点
static SLNode *destroyNode(SLNode *node){
    SLNode *next = node->next;
    free(node);
    return next;
    
}

//并初始化为空堆栈
void stackInit(MYStack *stack){
    stack->top = NULL;
}
//释放剩余节点并恢复到初始状态
void stackDelete(MYStack *stack){
    while (stack->top) {
        stack->top = destroyNode(stack->top);
    }
}
//判断堆栈是否为空
int stackEmpty(MYStack *stack){
    return ! stack->top;
}
//push
void stackPush(MYStack *stack,int data){
    stack->top = createNode(stack->top,data);
}
//pop
int stackPop(MYStack *stack){
    int value = stack->top->data;
    stack->top = destroyNode(stack->top);
    return value;
}
//获取容量
size_t stackSize(MYStack *stack){
    size_t size = 0;
    SLNode *node = NULL;
    for (node = stack->top; node; node = node->next) {
         ++ size;
    }
    return size;
}
//获取栈顶
int stackTop(MYStack *stack){
    return stack->top->data;
}



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Freertos中的堆栈和启动文件中的堆栈是两个不同的概念。在Freertos中,堆栈是用来保存任务的上下文信息的内存区域,用于任务切换时保存和恢复任务的执行状态。而启动文件中的堆栈是用来为整个程序提供内存空间的,包括全局变量、静态变量等。 在Freertos中,堆的大小可以通过在FreeRTOSConfig.h文件中设置configTOTAL_HEAP_SIZE来指定。这个值决定了Freertos可以使用的堆的总大小。根据经验,堆的大小应该设置得足够大,以满足任务的内存需求。 而启动文件中的堆栈大小与Freertos中的堆大小没有直接关系。启动文件中的堆栈大小是用来为整个程序提供内存空间的,包括全局变量、静态变量等。在使用Freertos时,启动文件中的堆栈大小可以根据以下公式来设置:启动文件中的heap_size = mcu运行时的ram空间 - RW-Data - ZI-Data - Freertos中设置的堆大小。 总结起来,Freertos中的堆栈和启动文件中的堆栈是两个不同的概念,它们的大小设置是独立的。在使用Freertos时,需要根据任务的内存需求来设置Freertos中的堆大小,并根据公式来设置启动文件中的堆栈大小,以确保程序的正常运行。 #### 引用[.reference_title] - *1* *2* *3* [stm32以及freertos 堆栈解析](https://blog.csdn.net/sinat_36568888/article/details/124320985)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值