c语言实现系列--如何用c语言实现栈数据结构

栈是一种先进后出的数据结构,主要操作有

push--压栈

pop--弹出

top--查看栈顶元素

isempty--检查栈是否为空

c语言实现方案

一、使用数组实现固定大小的栈

思路:在结构体中定义固定大小的数和栈顶指针

代码如下


#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

// 初始化栈
void initStack(Stack *s) {
    s->top = -1;
}

// 检查栈是否为空
bool isEmpty(Stack *s) {
    return s->top == -1;
}

// 检查栈是否已满
bool isFull(Stack *s) {
    return s->top == MAX_SIZE - 1;
}

// 压入元素
void push(Stack *s, int value) {
    if (isFull(s)) {
        printf("栈已满,无法压入元素 %d\n", value);
        return;
    }
    s->data[++s->top] = value;
}

// 弹出元素
int pop(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空,无法弹出元素\n");
        return -1; // 错误码
    }
    return s->data[s->top--];
}

// 查看栈顶元素
int peek(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空\n");
        return -1; // 错误码
    }
    return s->data[s->top];
}

// 示例用法
int main() {
    Stack s;
    initStack(&s);
    
    push(&s, 10);
    push(&s, 20);
    push(&s, 30);
    
    printf("栈顶元素: %d\n", peek(&s)); // 输出 30
    
    printf("弹出元素: %d\n", pop(&s));   // 输出 30
    printf("弹出元素: %d\n", pop(&s));   // 输出 20
    
    return 0;
}

二、使用动态内存分配实现可变大小的栈

这种实现方式更加灵活,可以根据需要动态调整栈的大小。


typedef struct {
    int *data;
    int top;
    int capacity;
} Stack;

// 初始化栈
void initStack(Stack *s, int capacity) {
    s->data = (int*)malloc(capacity * sizeof(int));
    s->top = -1;
    s->capacity = capacity;
}

// 检查栈是否为空
bool isEmpty(Stack *s) {
    return s->top == -1;
}

// 检查栈是否已满
bool isFull(Stack *s) {
    return s->top == s->capacity - 1;
}

// 扩展栈容量
void resize(Stack *s) {
    int newCapacity = s->capacity * 2;
    int *newData = (int*)realloc(s->data, newCapacity * sizeof(int));
    if (newData == NULL) {
        printf("内存分配失败\n");
        return;
    }
    s->data = newData;
    s->capacity = newCapacity;
    printf("栈容量已扩展到 %d\n", newCapacity);
}

// 压入元素
void push(Stack *s, int value) {
    if (isFull(s)) {
        resize(s);
    }
    s->data[++s->top] = value;
}

// 弹出元素
int pop(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空,无法弹出元素\n");
        return -1; // 错误码
    }
    return s->data[s->top--];
}

// 查看栈顶元素
int peek(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空\n");
        return -1; // 错误码
    }
    return s->data[s->top];
}

// 释放栈内存
void freeStack(Stack *s) {
    free(s->data);
    s->data = NULL;
    s->top = -1;
    s->capacity = 0;
}

// 示例用法
int main() {
    Stack s;
    initStack(&s, 5); // 初始容量为5
    
    for (int i = 0; i < 10; i++) {
        push(&s, i);
    }
    
    printf("栈顶元素: %d\n", peek(&s)); // 输出 9
    
    while (!isEmpty(&s)) {
        printf("弹出元素: %d\n", pop(&s));
    }
    
    freeStack(&s);
    return 0;
}

三、使用链表实现栈

// 定义栈节点
typedef struct Node {
    int data;
    struct Node *next;
} Node;
// 定义栈结构
typedef struct {
    Node *top;
} Stack;

// 初始化栈
void initStack(Stack *s) {
    s->top = NULL;
}

// 检查栈是否为空
bool isEmpty(Stack *s) {
    return s->top == NULL;
}

// 压入元素
void push(Stack *s, int value) {
    Node *newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("内存分配失败\n");
        return;
    }
    newNode->data = value;
    newNode->next = s->top;
    s->top = newNode;
}

// 弹出元素
int pop(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空,无法弹出元素\n");
        return -1; // 错误码
    }
    Node *temp = s->top;
    int value = temp->data;
    s->top = s->top->next;
    free(temp);
    return value;
}

// 查看栈顶元素
int peek(Stack *s) {
    if (isEmpty(s)) {
        printf("栈为空\n");
        return -1; // 错误码
    }
    return s->top->data;
}

// 释放栈内存
void freeStack(Stack *s) {
    while (!isEmpty(s)) {
        pop(s);
    }
}

// 示例用法
int main() {
    Stack s;
    initStack(&s);
    
    push(&s, 10);
    push(&s, 20);
    push(&s, 30);
    
    printf("栈顶元素: %d\n", peek(&s)); // 输出 30
    
    printf("弹出元素: %d\n", pop(&s));   // 输出 30
    printf("弹出元素: %d\n", pop(&s));   // 输出 20
    
    freeStack(&s);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值