用C语言实现栈:从基础到实战
栈(Stack)是一种基础的数据结构,遵循后进先出(LIFO,Last In First Out)的原则。它被广泛应用于函数调用、表达式求值、括号匹配等问题中。在这篇技术博客中,我们将详细介绍如何使用C语言实现一个栈,并涵盖基本的操作以及实战应用。
什么是栈?
栈是一种特殊的线性表,只允许在一端进行插入和删除操作。这一端被称为栈顶(Top)。栈的基本操作包括:
- Push: 将元素压入栈顶。
- Pop: 从栈顶移除元素。
- Peek/Top: 查看栈顶元素而不移除。
- IsEmpty: 判断栈是否为空。
- IsFull: 判断栈是否已满(对于有固定容量的栈)。
栈的实现方法
在C语言中,栈的实现可以分为基于数组和基于链表两种方法。我们将分别介绍这两种实现方式。
1. 基于数组实现栈
基于数组的栈实现通常适用于固定大小的栈。以下是代码示例:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack *stack) {
stack->top = -1;
}
// 判断栈是否为空
int isEmpty(Stack *stack) {
return stack->top == -1;
}
// 判断栈是否已满
int isFull(Stack *stack) {
return stack->top == MAX_SIZE - 1;
}
// 压栈操作
void push(Stack *stack, int value) {
if (isFull(stack)) {
printf("Stack overflow! Cannot push %d\n", value);
return;
}
stack->data[++stack->top] = value;
}
// 弹栈操作
int pop(Stack *stack) {
if (isEmpty(stack)) {
printf("Stack underflow! Cannot pop\n");
return -1;
}
return stack->data[stack->top--];
}
// 查看栈顶元素
int peek(Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty! Cannot peek\n");
return -1;
}
return stack->data[stack->top];
}
// 打印栈中元素
void printStack(Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty!\n");
return;
}
printf("Stack elements: ");
for (int i = 0; i <= stack->top; i++) {
printf("%d ", stack->data[i]);
}
printf("\n");
}
int main() {
Stack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
printStack(&stack);
printf("Popped: %d\n", pop(&stack));
printStack(&stack);
printf("Top element: %d\n", peek(&stack));
return 0;
}
核心特点:
- 使用数组存储数据。
- 通过
top
变量管理栈顶位置。 - 操作简单但存在固定容量的限制。
2. 基于链表实现栈
链表实现的栈不需要固定大小,动态分配内存,适用于需要灵活容量的场景。
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int data;
struct Node *next;
} Node;
// 初始化栈
Node* initStack() {
return NULL;
}
// 判断栈是否为空
int isEmpty(Node *top) {
return top == NULL;
}
// 压栈操作
void push(Node **top, int value) {
Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed! Cannot push %d\n", value);
return;
}
newNode->data = value;
newNode->next = *top;
*top = newNode;
}
// 弹栈操作
int pop(Node **top) {
if (isEmpty(*top)) {
printf("Stack underflow! Cannot pop\n");
return -1;
}
Node *temp = *top;
int value = temp->data;
*top = temp->next;
free(temp);
return value;
}
// 查看栈顶元素
int peek(Node *top) {
if (isEmpty(top)) {
printf("Stack is empty! Cannot peek\n");
return -1;
}
return top->data;
}
// 打印栈中元素
void printStack(Node *top) {
if (isEmpty(top)) {
printf("Stack is empty!\n");
return;
}
printf("Stack elements: ");
Node *current = top;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
int main() {
Node *stack = initStack();
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
printStack(stack);
printf("Popped: %d\n", pop(&stack));
printStack(stack);
printf("Top element: %d\n", peek(stack));
return 0;
}
核心特点:
- 动态分配内存,无容量限制。
- 通过链表节点表示栈元素。
- 实现更加灵活,但需要注意内存管理。
实战案例:括号匹配问题
栈可以用于解决括号匹配的问题。以下是一个简单的实现:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
typedef struct {
char data[MAX_SIZE];
int top;
} CharStack;
// 初始化字符栈
void initCharStack(CharStack *stack) {
stack->top = -1;
}
// 判断栈是否为空
int isCharStackEmpty(CharStack *stack) {
return stack->top == -1;
}
// 压栈操作
void pushChar(CharStack *stack, char ch) {
if (stack->top == MAX_SIZE - 1) {
printf("Stack overflow! Cannot push %c\n", ch);
return;
}
stack->data[++stack->top] = ch;
}
// 弹栈操作
char popChar(CharStack *stack) {
if (isCharStackEmpty(stack)) {
printf("Stack underflow! Cannot pop\n");
return '\0';
}
return stack->data[stack->top--];
}
// 检查括号匹配
int isBalanced(const char *expr) {
CharStack stack;
initCharStack(&stack);
for (int i = 0; i < strlen(expr); i++) {
char ch = expr[i];
if (ch == '(' || ch == '{' || ch == '[') {
pushChar(&stack, ch);
} else if (ch == ')' || ch == '}' || ch == ']') {
if (isCharStackEmpty(&stack)) {
return 0; // 多余的右括号
}
char top = popChar(&stack);
if ((ch == ')' && top != '(') ||
(ch == '}' && top != '{') ||
(ch == ']' && top != '[')) {
return 0; // 括号不匹配
}
}
}
return isCharStackEmpty(&stack);
}
int main() {
const char *expr = "{[()]}";
if (isBalanced(expr)) {
printf("The expression is balanced.\n");
} else {
printf("The expression is not balanced.\n");
}
return 0;
}
总结
通过这篇博客,我们从基础概念到代码实现,深入探讨了如何使用C语言实现栈。无论是数组还是链表方法,各有优缺点。栈的应用范围广泛,是编程中不可或缺的工具。希望这篇文章能帮助您更好地理解和掌握栈的实现与应用!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!