1. 基于数组的栈实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义栈的最大容量
#define MAX_SIZE 100
// 定义栈结构
typedef struct {
int data[MAX_SIZE]; // 存储数据的数组
int top; // 栈顶指针
} Stack;
// 初始化栈
void initStack(Stack* s) {
s->top = -1; // 栈空时top为-1
}
// 判断栈是否为空
bool isEmpty(Stack* s) {
return s->top == -1;
}
// 判断栈是否已满
bool isFull(Stack* s) {
return s->top == MAX_SIZE - 1;
}
// 入栈操作
bool push(Stack* s, int value) {
if (isFull(s)) {
printf("栈已满,无法入栈!\n");
return false;
}
s->data[++(s->top)] = value;
return true;
}
// 出栈操作
bool pop(Stack* s, int* value) {
if (isEmpty(s)) {
printf("栈为空,无法出栈!\n");
return false;
}
*value = s->data[(s->top)--];
return true;
}
// 获取栈顶元素
bool peek(Stack* s, int* value) {
if (isEmpty(s)) {
printf("栈为空!\n");
return false;
}
*value = s->data[s->top];
return true;
}
// 获取栈中元素个数
int size(Stack* s) {
return s->top + 1;
}
// 清空栈
void clearStack(Stack* s) {
s->top = -1;
}
// 测试栈的基本操作
int main() {
Stack stack;
initStack(&stack);
// 入栈测试
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
printf("栈中元素个数: %d\n", size(&stack));
// 查看栈顶元素
int topValue;
if (peek(&stack, &topValue)) {
printf("栈顶元素: %d\n", topValue);
}
// 出栈测试
int value;
while (pop(&stack, &value)) {
printf("出栈元素: %d\n", value);
}
return 0;
}
2. 基于链表的栈实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// 定义栈节点
typedef struct StackNode {
int data;
struct StackNode* next;
} StackNode;
// 定义栈结构
typedef struct {
StackNode* top; // 栈顶指针
int size; // 栈大小
} LinkedStack;
// 初始化栈
void initStack(LinkedStack* s) {
s->top = NULL;
s->size = 0;
}
// 判断栈是否为空
bool isEmpty(LinkedStack* s) {
return s->top == NULL;
}
// 入栈操作
bool push(LinkedStack* s, int value) {
StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
if (newNode == NULL) {
printf("内存分配失败!\n");
return false;
}
newNode->data = value;
newNode->next = s->top;
s->top = newNode;
s->size++;
return true;
}
// 出栈操作
bool pop(LinkedStack* s, int* value) {
if (isEmpty(s)) {
printf("栈为空,无法出栈!\n");
return false;
}
StackNode* temp = s->top;
*value = temp->data;
s->top = temp->next;
free(temp);
s->size--;
return true;
}
// 获取栈顶元素
bool peek(LinkedStack* s, int* value) {
if (isEmpty(s)) {
printf("栈为空!\n");
return false;
}
*value = s->top->data;
return true;
}
// 获取栈大小
int size(LinkedStack* s) {
return s->size;
}
// 清空栈
void clearStack(LinkedStack* s) {
int value;
while (pop(s, &value)); // 持续出栈直到栈空
}
// 销毁栈
void destroyStack(LinkedStack* s) {
clearStack(s);
s->top = NULL;
s->size = 0;
}
// 测试链式栈的基本操作
int main() {
LinkedStack stack;
initStack(&stack);
// 入栈测试
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
printf("栈中元素个数: %d\n", size(&stack));
// 查看栈顶元素
int topValue;
if (peek(&stack, &topValue)) {
printf("栈顶元素: %d\n", topValue);
}
// 出栈测试
int value;
while (pop(&stack, &value)) {
printf("出栈元素: %d\n", value);
}
// 销毁栈
destroyStack(&stack);
return 0;
}
3. 栈的应用示例
3.1 括号匹配检查
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#define MAX_SIZE 100
typedef struct {
char data[MAX_SIZE];
int top;
} CharStack;
void initStack(CharStack* s) {
s->top = -1;
}
bool push(CharStack* s, char c) {
if (s->top >= MAX_SIZE - 1) return false;
s->data[++(s->top)] = c;
return true;
}
bool pop(CharStack* s, char* c) {
if (s->top == -1) return false;
*c = s->data[(s->top)--];
return true;
}
// 检查括号是否匹配
bool checkBrackets(const char* expr) {
CharStack stack;
initStack(&stack);
for (int i = 0; expr[i] != '\0'; i++) {
if (expr[i] == '(' || expr[i] == '[' || expr[i] == '{') {
push(&stack, expr[i]);
} else if (expr[i] == ')' || expr[i] == ']' || expr[i] == '}') {
char top;
if (!pop(&stack, &top)) return false;
if ((expr[i] == ')' && top != '(') ||
(expr[i] == ']' && top != '[') ||
(expr[i] == '}' && top != '{')) {
return false;
}
}
}
return stack.top == -1; // 栈应该为空
}
3.2 中缀表达式转后缀表达式
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX_SIZE 100
typedef struct {
char data[MAX_SIZE];
int top;
} CharStack;
// 获取运算符优先级
int getPriority(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
// 中缀转后缀
void infixToPostfix(const char* infix, char* postfix) {
CharStack stack;
initStack(&stack);
int j = 0;
for (int i = 0; infix[i] != '\0'; i++) {
if (isdigit(infix[i])) {
// 数字直接输出
postfix[j++] = infix[i];
} else if (infix[i] == '(') {
// 左括号入栈
push(&stack, infix[i]);
} else if (infix[i] == ')') {
// 右括号时,弹出栈中运算符直到遇到左括号
char op;
while (pop(&stack, &op) && op != '(') {
postfix[j++] = op;
}
} else {
// 运算符
while (stack.top >= 0 &&
getPriority(stack.data[stack.top]) >= getPriority(infix[i])) {
postfix[j++] = stack.data[stack.top--];
}
push(&stack, infix[i]);
}
}
// 处理栈中剩余的运算符
while (stack.top >= 0) {
postfix[j++] = stack.data[stack.top--];
}
postfix[j] = '\0';
}
3.3 函数调用栈模拟
#include <stdio.h>
#include <string.h>
#define MAX_FRAME_SIZE 100
#define MAX_STACK_SIZE 1000
// 函数调用帧
typedef struct {
char functionName[50];
int localVars[MAX_FRAME_SIZE];
int returnAddress;
} StackFrame;
// 调用栈
typedef struct {
StackFrame frames[MAX_STACK_SIZE];
int top;
} CallStack;
void initCallStack(CallStack* cs) {
cs->top = -1;
}
// 压入新的函数调用帧
void pushFrame(CallStack* cs, const char* funcName, int retAddr) {
cs->top++;
strcpy(cs->frames[cs->top].functionName, funcName);
cs->frames[cs->top].returnAddress = retAddr;
}
// 弹出函数调用帧
void popFrame(CallStack* cs) {
if (cs->top >= 0) {
printf("Return from function: %s\n",
cs->frames[cs->top].functionName);
cs->top--;
}
}
// 模拟函数调用
void simulateFunctionCalls() {
CallStack cs;
initCallStack(&cs);
// 模拟main函数调用
pushFrame(&cs, "main", 0);
printf("Entering main()\n");
// 模拟foo函数调用
pushFrame(&cs, "foo", 100);
printf("main() calls foo()\n");
// 模拟bar函数调用
pushFrame(&cs, "bar", 200);
printf("foo() calls bar()\n");
// 模拟函数返回
popFrame(&cs); // bar returns
popFrame(&cs); // foo returns
popFrame(&cs); // main returns
}