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

#define MAX_SIZE 100  // 栈的最大容量
typedef int ElemType;  // 定义元素类型

// 顺序栈结构体定义
typedef struct {
    ElemType data[MAX_SIZE];  // 存储数据的数组
    int top;     // 栈顶指针，指向栈顶元素
} SeqStack;

// 创建顺序栈
SeqStack* createStack() {
    SeqStack *stack = (SeqStack *)malloc(sizeof(SeqStack));  // 分配栈的内存
    if (stack == NULL) {
        printf("内存分配失败\n");
        return NULL;  // 内存分配失败
    }
    
	if (stack->data == NULL) {
        printf("数据区内存分配失败\n");
        free(stack);
        return NULL;  // 数据区内存分配失败
    }
    stack->top = -1;  // 初始化栈顶指针
    return stack;
}

// 判断栈是否为空
int isEmpty(SeqStack *stack) {
    return stack->top == -1;  // 如果栈顶指针为-1，栈为空
}

// 判断栈是否已满
int isFull(SeqStack *stack) {
    return stack->top == MAX_SIZE - 1;  // 如果栈顶指针为最大容量-1，栈已满
}

// 入栈操作
int push(SeqStack *stack, int elem) {
    if (isFull(stack)) {
        printf("栈已满，无法入栈\n");
        return 0;  // 入栈失败
    }
    stack->data[++stack->top] = elem;  // 将元素推入栈中并更新栈顶指针
    return 1;  // 入栈成功
}

// 出栈操作
int pop(SeqStack *stack, int *elem) {
    if (isEmpty(stack)) {
        printf("栈为空，无法出栈\n");
        return 0;  // 出栈失败
    }
    *elem = stack->data[stack->top--];  // 获取栈顶元素并更新栈顶指针
    return 1;  // 出栈成功
}

// 获取栈顶元素
int top(SeqStack *stack, int *elem) {
    if (isEmpty(stack)) {
        printf("栈为空\n");
        return 0;  // 获取栈顶元素失败
    }
    *elem = stack->data[stack->top];  // 获取栈顶元素
    return 1;  // 获取栈顶元素成功
}

// 释放栈的内存
void freeStack(SeqStack *stack) {
    if (stack != NULL) {
        free(stack->data);  // 释放栈的数据区内存
        free(stack);  // 释放栈的结构体内存
    }
}

// 测试代码
int main() {
    SeqStack *stack = createStack();  // 创建顺序栈
    if (stack == NULL) {
        return 1;
    }

    printf("入栈元素(入栈顺序为 10 20 30) \n");
    push(stack, 10);
    push(stack, 20);
    push(stack, 30);

    int topElem;
    if (top(stack, &topElem)) {
        printf("栈顶元素是: %d\n", topElem);  // 打印栈顶元素
    }

    printf("出栈元素：\n");
    int poppedElem;
    while (!isEmpty(stack)) {
        pop(stack, &poppedElem);
        printf("出栈元素: %d\n", poppedElem);
    }

    // 测试完毕，释放内存
    freeStack(stack);

    return 0;
}