包含min函数的栈(最小栈)C语言版

该博客介绍了一个数据结构问题,如何在一个栈中实现min功能,使得min、push和pop操作的时间复杂度均为O(1)。通过维护两个栈,一个用于存储所有元素,另一个仅存储最小值,确保在任何时候都能快速获取最小值。当新元素小于或等于当前最小值时,两个栈都插入新元素;否则,只在普通栈中插入新元素。这样在删除元素时,最小栈始终保持最小值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。

https://leetcode-cn.com/problems/bao-han-minhan-shu-de-zhan-lcof/

示例:
在这里插入图片描述
代码(前面都是实现栈的接口,实际代码很短):

MinStack* minStackCreate() {
    MinStack* obj = (MinStack*)malloc(sizeof(stack)*2);
    StackInit(&obj->s);
    StackInit(&obj->min);
    return obj;
}

void minStackPush(MinStack* obj, int x) {
    if(stackEmpty(&obj->s))
    {
        stackPush(&obj->s,x);
        stackPush(&obj->min,x);
    }
    else
    {
        if(x<=stackTop(&obj->min))//如果插入的值比最小值要小就两个栈都要插入
        {
            stackPush(&obj->s,x);
            stackPush(&obj->min,x);
        }
        else//否则只插入s,min里面继续插入最小值
        {
            stackPush(&obj->s,x);
            stackPush(&obj->min,stackTop(&obj->min));
        }
    }
}

void minStackPop(MinStack* obj) {
    stackPop(&obj->s);
    stackPop(&obj->min);
}

int minStackTop(MinStack* obj) {
    return stackTop(&obj->s);
}

int minStackMin(MinStack* obj) {
    return stackTop(&obj->min);
}

void minStackFree(MinStack* obj) {
    stackDestroy(&obj->s);
    stackDestroy(&obj->min);
    free(obj);
    obj = NULL;
}

思路:用两个栈实现,其中一个栈正常插入数据,另外一个栈专门储存插入中的最小那个值。

插入思路

下面是代码角度的思路:
在这里插入图片描述
逻辑上讲:每次插入一个新元素,都要与前面一个插入的元素相比较的原因是要保证找出最小的那个元素。

  1. 如果新元素是最小的,就同时插入最小栈和普通栈。
  2. 如果不是最小的,插入普通栈,然后在min栈里面插入一个之前最小的元素。(原因:删除的时候有可能把最小的元素删除掉,你要有足够的元素去更新换代,如果不插入可能会导致最小栈变成空了。)

删除思路
在这里插入图片描述
返回最小值思路
在这里插入图片描述

在C语言中,`min` 函数用于获取两个数中的最小值。C语言标准库中并没有直接提供 `min` 函数,因此通常需要通过宏定义或自定义函数的方式来实现。 ### 通过宏定义实现 `min` 功能 宏定义是一种常见的方式,可以在代码开始前通过预处理指令定义: ```c #define min(a, b) ((a) < (b) ? (a) : (b)) ``` 该宏定义可以用于获取两个值中的最小值,使用时需要注意参数的类型和表达式副作用。例如: ```c int x = 10; int y = 20; int result = min(x, y); // result will be 10 ``` ### 自定义函数实现 `min` 除了宏定义之外,还可以通过编写函数来实现 `min` 功能,这种方式更加安全,适用于复杂的逻辑或避免宏展开带来的问题: ```c int min(int a, int b) { return a < b ? a : b; } ``` 使用函数实现时,可以避免宏定义中可能出现的多次求值问题,同时支持调试和类型检查。 ### 示例代码 以下是一个完整的示例,展示了宏定义和函数两种方式的使用: ```c #include <stdio.h> // 宏定义实现 min #define min_macro(a, b) ((a) < (b) ? (a) : (b)) // 函数实现 min int min_function(int a, int b) { return a < b ? a : b; } int main() { int x = 15; int y = 10; // 使用宏定义 int result1 = min_macro(x, y); printf("Min (macro): %d\n", result1); // 使用函数 int result2 = min_function(x, y); printf("Min (function): %d\n", result2); return 0; } ``` ### 宏与函数的对比 - **宏的优势**:执行效率高,因为宏在预处理阶段直接替换代码,没有函数调用的开销。 - **函数的优势**:更安全,便于调试,支持类型检查,避免了宏定义中可能出现的副作用[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值