You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言中以数组首元素为栈顶实现栈的疑问求解

实现栈顶固定在arr[0]的C语言栈

嘿,这个需求其实就是把常规栈的存储逻辑反过来玩——通常我们的栈是往数组下标增大的方向存元素,栈顶随元素增加“向右跑”,但现在要求栈顶固定在arr[0],新元素必须放在这里,旧元素得乖乖往后“让位”。我给你一步步拆解实现思路和代码:

核心逻辑先理清

要满足arr[0]是栈顶(也就是最后入栈的元素永远在这个位置),得记住这几点:

  • 入栈时:先把已有的所有元素向后移动一位,给新元素腾位置,再把新元素放到arr[0]
  • 出栈时:先取出arr[0]的值,再把剩下的元素向前移动一位,保证下一个栈顶还是arr[0]
  • 需要用一个变量记录当前栈里的元素数量,用来判断栈空/栈满,以及移动元素时的边界

1. 定义栈的结构体

首先我们需要一个结构体来封装栈的数组、最大容量和当前元素数量:

#define MAX_STACK_SIZE 100  // 可以根据需求调整栈的最大容量

typedef struct {
    int arr[MAX_STACK_SIZE];  // 存储栈元素的数组
    int size;                 // 当前栈的元素个数,初始为0
} Stack;

这里用size代替常规栈的top下标,因为我们的栈顶位置是固定的,只需要知道有多少元素在栈里就行。

2. 初始化栈

初始化超级简单,把size设为0就代表栈是空的:

void initStack(Stack *stack) {
    stack->size = 0;
}

3. 栈空/栈满判断

这两个辅助函数是栈操作的基础:

  • 栈空:size == 0,此时arr[0]没有有效数据
  • 栈满:size == MAX_STACK_SIZE,数组已经放满,没法再往后挪元素了
// 判断栈是否为空,空返回1,非空返回0
int isEmpty(Stack *stack) {
    return stack->size == 0;
}

// 判断栈是否已满,满返回1,未满返回0
int isFull(Stack *stack) {
    return stack->size == MAX_STACK_SIZE;
}

4. 入栈操作(Push)

入栈的关键是从后往前移动已有元素,避免覆盖数据,然后把新元素放到arr[0]:

// 入栈:成功返回1,栈满返回0
int push(Stack *stack, int value) {
    if (isFull(stack)) {
        printf("栈已满,无法入栈!\n");
        return 0;
    }

    // 从最后一个元素开始,依次向后挪一位(防止前面的元素被覆盖)
    for (int i = stack->size; i > 0; i--) {
        stack->arr[i] = stack->arr[i-1];
    }

    // 新元素放到栈顶(arr[0])
    stack->arr[0] = value;
    stack->size++;
    return 1;
}

这里一定要注意循环方向:如果从i=0开始往前挪,会把arr[0]的值覆盖到arr[1],导致原来的arr[1]数据丢失,所以必须从当前元素的末尾开始移动。

5. 出栈操作(Pop)

出栈的关键是取出arr[0]后,把后面的元素依次向前挪,保持栈顶始终在arr[0]:

// 出栈:成功返回元素值,栈空返回-1(可以根据需求调整错误处理逻辑)
int pop(Stack *stack) {
    if (isEmpty(stack)) {
        printf("栈已空,无法出栈!\n");
        return -1;
    }

    int topValue = stack->arr[0];  // 取出栈顶元素

    // 把后面的元素依次向前挪一位
    for (int i = 0; i < stack->size - 1; i++) {
        stack->arr[i] = stack->arr[i+1];
    }

    stack->size--;
    return topValue;
}

6. 获取栈顶元素(Peek)

因为栈顶固定在arr[0],直接返回它就行,记得先判断栈是否为空:

// 获取栈顶元素:成功返回值,栈空返回-1
int peek(Stack *stack) {
    if (isEmpty(stack)) {
        printf("栈已空,无栈顶元素!\n");
        return -1;
    }
    return stack->arr[0];
}

测试一下代码

写个main函数验证一下逻辑是否正确:

#include <stdio.h>

// 把上面的结构体和函数都放在这里

int main() {
    Stack stack;
    initStack(&stack);

    push(&stack, 10);
    push(&stack, 20);
    push(&stack, 30);

    printf("当前栈顶元素:%d\n", peek(&stack));  // 输出30(最后入栈的元素在arr[0])
    printf("出栈元素:%d\n", pop(&stack));       // 输出30
    printf("当前栈顶元素:%d\n", peek(&stack));  // 输出20

    push(&stack, 40);
    printf("当前栈顶元素:%d\n", peek(&stack));  // 输出40

    return 0;
}

和常规栈的区别

常规栈用top下标(初始-1或0),入栈时top++直接放元素,不需要移动数据,效率更高。但你的任务要求栈顶固定在arr[0],就必须用元素移动的方式实现——这是一种 trade-off,牺牲了一点效率,但满足了特定的存储要求。

如果觉得每次移动元素太繁琐,有没有其他思路?其实也可以把数组当成“倒过来”用,但本质上还是要维护栈顶在arr[0]的逻辑,所以核心还是元素移动,毕竟位置是固定死的。

内容的提问来源于stack exchange,提问作者user9471318

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 09:00:41