栈和单调栈的详细介绍和代码实现

栈(Stack)是一种常见的数据结构,遵循后进先出(LIFO)的原则。它类似于现实生活中的堆叠物品,最后放入的物品会最先被取出。接下来将逐一介绍栈的基本概念、核心操作和实现方式,并最后介绍单调栈。

栈的基本介绍

栈是一种线性数据结构,由一系列元素组成,它只允许在一端进行插入和删除操作。这一端通常称为栈顶。栈遵循后进先出的原则,即最后一个入栈的元素将会最先被出栈。栈通常具有压栈(push)、弹栈(pop)、取栈顶元素(top)和判空等基本操作。

栈的插入

栈的插入操作又称为压栈,将一个元素添加到栈顶。压栈操作需要保证栈顶指针指向插入的位置,并将元素放入该位置。

栈的删除

栈的删除操作又称为弹栈,从栈顶移除一个元素并返回它。弹栈操作需要保证栈顶指针指向正确的位置,并返回该位置的元素。

C++ STL 实现

在 C++ 标准模板库中,栈可以使用 <stack> 头文件中的 stack 模板类来实现。该模板类提供了压栈、弹栈、取栈顶元素、判空等核心操作,使用起来非常方便。

#include <stack>

std::stack<int> s; // 声明整型栈
s.push(1); // 压栈,将元素 1 添加到栈顶
s.pop(); // 弹栈,移除栈顶元素
int topElement = s.top(); // 获取栈顶元素的值
bool isEmpty = s.empty(); // 判断栈是否为空

C 语言手写实现

在 C 语言中,可以使用数组或链表手动实现栈。使用数组实现时,需要维护栈顶指针,插入和删除操作需要移动指针和数据。使用链表实现时,可以考虑使用头指针来表示栈顶。

单调栈的基本介绍

单调栈(Monotonic Stack)是栈的一种特殊应用,主要用于解决找下一个更大元素、找下一个更小元素等问题。单调栈不再遵循严格的后进先出原则,而是具有一定的单调性,通常是单调递增或单调递减。

单调栈的插入

单调栈的插入操作类似于普通栈,将一个元素添加到栈顶。不同之处在于,插入元素后需要调整栈内的元素,以保持单调性,通常是保持单调递增或单调递减。

单调栈的删除

单调栈的删除操作也类似于普通栈,从栈顶移除一个元素并返回它。同样需要根据单调性进行相应的调整。

C++ STL 实现单调栈

C++标准模板库(STL)中没有提供直接的单调栈实现,但我们可以利用std::stack结合其他数据结构和算法来实现单调栈。以下是一个示例,以单调递增栈为例:

#include <stack>
#include <vector>

std::vector<int> findNextGreaterElements(std::vector<int>& nums) {
    int n = nums.size();
    std::vector<int> result(n, -1);
    std::stack<int> monoStack; // 单调递增栈,存储元素的下标

    for (int i = 0; i < n; i++) {
        while (!monoStack.empty() && nums[i] > nums[monoStack.top()]) {
            result[monoStack.top()] = nums[i]; // 当前元素是栈顶元素的下一个更大元素
            monoStack.pop();
        }
        monoStack.push(i); // 将当前元素的下标压入栈中
    }

    return result;
}

在上述示例中,我们使用std::stack实现了一个单调递增栈。我们遍历输入数组nums,对于每个元素,如果它比栈顶元素大,则将栈顶元素的下一个更大元素更新为当前元素,并将栈顶元素弹出。最后,将当前元素的下标压入栈中。这样,我们就可以在result数组中找到每个元素的下一个更大元素了。

C 语言手写实现单调栈

在 C 语言中,可以通过使用数组和相关的算法来手动实现单调栈。以下是一个示例,以单调递增栈为例:

#include <stdio.h>
#include <stdlib.h>

struct Stack {
    int* array;
    int size;
    int top;
};

struct Stack* createStack(int maxSize) {
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->array = (int*)malloc(maxSize * sizeof(int));
    stack->size = maxSize;
    stack->top = -1;
    return stack;
}

int isEmpty(struct Stack* stack) {
    return stack->top == -1;
}

void push(struct Stack* stack, int num) {
    stack->array[++stack->top] = num;
}

int pop(struct Stack* stack) {
    if (isEmpty(stack)) {
        printf("Stack is empty\n");
        return -1;
    }
    return stack->array[stack->top--];
}

// 寻找nums数组中每个元素的下一个更大元素
int* findNextGreaterElements(int* nums, int numsSize) {
    int* result = (int*)malloc(numsSize * sizeof(int));
    struct Stack* monoStack = createStack(numsSize);

    for (int i = 0; i < numsSize; i++) {
        while (!isEmpty(monoStack) && nums[i] > nums[monoStack->array[monoStack->top]]) {
            result[monoStack->array[monoStack->top]] = nums[i]; // 当前元素是栈顶元素的下一个更大元素
            pop(monoStack);
        }
        push(monoStack, i); // 将当前元素的下标压入栈中
    }

    while (!isEmpty(monoStack)) {
        result[monoStack->array[monoStack->top]] = -1; // 栈中剩余元素的下一个更大元素不存在
        pop(monoStack);
    }

    free(monoStack->array);
    free(monoStack);
    return result;
}

在这个示例中,我们使用了一个自定义的Stack结构体来实现单调递增栈。我们使用动态数组来存储栈元素,并利用常用的栈操作函数,如createStackisEmptypushpop等。我们遍历输入数组nums,对于每个元素,如果它比栈顶元素大,则将栈顶元素的下一个更大元素更新为当前元素,并将栈顶元素弹出。最后,将队列中剩余元素的下一个更大元素设置为-1。这样,我们就找到了每个元素的下一个更大元素。

如果你想更深入地了解人工智能的其他方面,比如机器学习、深度学习、自然语言处理等等,也可以点击这个链接,我按照如下图所示的学习路线为大家整理了100多G的学习资源,基本涵盖了人工智能学习的所有内容,包括了目前人工智能领域最新顶会论文合集和丰富详细的项目实战资料,可以帮助你入门和进阶。

链接: 人工智能交流群【最新顶会与项目实战】(点击跳转)

在这里插入图片描述

  • 51
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
在Python中,单调栈和单调队列是两种不同的数据结构。单调栈是一个,它的特点是内的元素是单调的,可以是递增或递减的。在构建单调栈时,元素的插入和弹出都是在的一端进行的。与此类似,单调队列也是一个队列,它的特点是队列内的元素是单调的,可以是递增或递减的。在构建单调队列时,元素的插入是在队列的一端进行的,而弹出则是选择队列头进行的。 单调队列在解决某些问题时,能够提升效率。例如,滑动窗口最大值问题可以通过使用单调队列来解决。单调队列的结构可以通过以下代码实现: ```python class MQueue: def __init__(self): self.queue = [] def push(self, value): while self.queue and self.queue[-1 < value: self.queue.pop(-1) self.queue.append(value) def pop(self): if self.queue: return self.queue.pop(0) ``` 上述代码定义了一个名为MQueue的类,它包含一个列表作为队列的存储结构。该类有两个方法,push和pop。push方法用于向队列中插入元素,它会删除队列尾部小于插入元素的所有元素,并将插入元素添加到队列尾部。pop方法用于弹出队列的头部元素。 总结来说,单调栈和单调队列都是为了解决特定问题而设计的数据结构。单调栈在构建时元素的插入和弹出都是在的一端进行的,而单调队列则是在队列的一端进行的。在Python中,可以通过自定义类来实现单调队列的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

RRRRRoyal

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

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

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

打赏作者

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

抵扣说明:

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

余额充值