您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# C语言怎么实现栈
## 1. 栈的基本概念
### 1.1 什么是栈
栈(Stack)是一种特殊的线性数据结构,它遵循**后进先出(LIFO, Last In First Out)**的原则。这意味着最后入栈的元素会最先被取出,类似于我们日常生活中叠放的盘子——总是从最上面取用。
### 1.2 栈的特性
- **限定性操作**:只允许在栈顶进行插入(push)和删除(pop)操作
- **单向性**:数据只能从栈顶进出
- **动态性**:栈的大小可动态变化(取决于实现方式)
### 1.3 栈的常见操作
| 操作 | 描述 |
|------|------|
| Push | 将元素压入栈顶 |
| Pop | 移除并返回栈顶元素 |
| Peek/Top | 查看栈顶元素但不移除 |
| isEmpty | 检查栈是否为空 |
| isFull | 检查栈是否已满(固定大小栈) |
## 2. 栈的C语言实现方式
### 2.1 基于数组的实现(顺序栈)
#### 2.1.1 数据结构定义
```c
#define MAX_SIZE 100 // 栈的最大容量
typedef struct {
int data[MAX_SIZE];
int top; // 栈顶指针
} ArrayStack;
void initStack(ArrayStack *stack) {
stack->top = -1; // 初始状态下栈为空
}
int push(ArrayStack *stack, int value) {
if (stack->top >= MAX_SIZE - 1) {
printf("Stack Overflow!\n");
return 0; // 入栈失败
}
stack->data[++stack->top] = value;
return 1; // 入栈成功
}
int pop(ArrayStack *stack) {
if (stack->top == -1) {
printf("Stack Underflow!\n");
return INT_MIN; // 返回最小值表示错误
}
return stack->data[stack->top--];
}
// 查看栈顶元素
int peek(ArrayStack *stack) {
if (stack->top == -1) {
printf("Stack is empty!\n");
return INT_MIN;
}
return stack->data[stack->top];
}
// 检查栈是否为空
int isEmpty(ArrayStack *stack) {
return stack->top == -1;
}
// 检查栈是否已满
int isFull(ArrayStack *stack) {
return stack->top == MAX_SIZE - 1;
}
typedef struct StackNode {
int data;
struct StackNode *next;
} StackNode;
typedef struct {
StackNode *top; // 栈顶指针
int size; // 栈当前大小(可选)
} LinkedStack;
void initLinkedStack(LinkedStack *stack) {
stack->top = NULL;
stack->size = 0;
}
void linkedPush(LinkedStack *stack, int value) {
StackNode *newNode = (StackNode*)malloc(sizeof(StackNode));
if (!newNode) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;
stack->size++;
}
int linkedPop(LinkedStack *stack) {
if (stack->top == NULL) {
printf("Stack Underflow!\n");
return INT_MIN;
}
StackNode *temp = stack->top;
int popped = temp->data;
stack->top = stack->top->next;
free(temp);
stack->size--;
return popped;
}
特性 | 数组实现 | 链表实现 |
---|---|---|
内存分配 | 静态固定大小 | 动态分配 |
空间效率 | 可能浪费或不足 | 按需分配 |
时间复杂度 | 所有操作O(1) | 所有操作O(1) |
实现复杂度 | 较简单 | 较复杂(需处理指针) |
扩容难度 | 困难(需重新分配) | 容易(自动扩展) |
缓存友好性 | 好(连续内存) | 较差(内存不连续) |
int isBalanced(char expr[]) {
ArrayStack stack;
initStack(&stack);
for (int i = 0; expr[i] != '\0'; i++) {
if (expr[i] == '(' || expr[i] == '[' || expr[i] == '{') {
push(&stack, expr[i]);
} else {
if (isEmpty(&stack)) return 0;
char top = pop(&stack);
if ((expr[i] == ')' && top != '(') ||
(expr[i] == ']' && top != '[') ||
(expr[i] == '}' && top != '{')) {
return 0;
}
}
}
return isEmpty(&stack);
}
int evaluatePostfix(char* exp) {
ArrayStack stack;
initStack(&stack);
for (int i = 0; exp[i]; i++) {
if (isdigit(exp[i])) {
push(&stack, exp[i] - '0');
} else {
int val1 = pop(&stack);
int val2 = pop(&stack);
switch (exp[i]) {
case '+': push(&stack, val2 + val1); break;
case '-': push(&stack, val2 - val1); break;
case '*': push(&stack, val2 * val1); break;
case '/': push(&stack, val2 / val1); break;
}
}
}
return pop(&stack);
}
当数组实现的栈容量不足时,可以自动扩容:
typedef struct {
int *data; // 动态数组指针
int top; // 栈顶指针
int capacity; // 当前容量
} DynamicStack;
void resize(DynamicStack *stack) {
stack->capacity *= 2;
stack->data = realloc(stack->data, stack->capacity * sizeof(int));
if (!stack->data) {
printf("Memory reallocation failed!\n");
exit(1);
}
}
#define TOTAL_SIZE 200
typedef struct {
int data[TOTAL_SIZE];
int top1; // 栈1的栈顶指针
int top2; // 栈2的栈顶指针
} DoubleStack;
// 初始化双栈
void initDoubleStack(DoubleStack *stack) {
stack->top1 = -1;
stack->top2 = TOTAL_SIZE;
}
// 栈1的push操作
int push1(DoubleStack *stack, int value) {
if (stack->top1 + 1 >= stack->top2) {
printf("Stack Overflow!\n");
return 0;
}
stack->data[++stack->top1] = value;
return 1;
}
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#define MAX_SIZE 10 // 减小栈大小便于测试溢出
typedef struct {
int data[MAX_SIZE];
int top;
} ArrayStack;
void initStack(ArrayStack *stack) {
stack->top = -1;
}
int isFull(ArrayStack *stack) {
return stack->top == MAX_SIZE - 1;
}
int isEmpty(ArrayStack *stack) {
return stack->top == -1;
}
int push(ArrayStack *stack, int value) {
if (isFull(stack)) {
printf("Stack Overflow!\n");
return 0;
}
stack->data[++stack->top] = value;
printf("Pushed %d to stack\n", value);
return 1;
}
int pop(ArrayStack *stack) {
if (isEmpty(stack)) {
printf("Stack Underflow!\n");
return INT_MIN;
}
printf("Popped %d from stack\n", stack->data[stack->top]);
return stack->data[stack->top--];
}
void display(ArrayStack *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() {
ArrayStack stack;
initStack(&stack);
push(&stack, 10);
push(&stack, 20);
push(&stack, 30);
display(&stack);
pop(&stack);
display(&stack);
// 测试栈溢出
for (int i = 0; i < MAX_SIZE + 2; i++) {
push(&stack, i);
}
// 测试栈下溢
for (int i = 0; i < MAX_SIZE + 2; i++) {
pop(&stack);
}
return 0;
}
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
typedef struct StackNode {
int data;
struct StackNode *next;
} StackNode;
typedef struct {
StackNode *top;
int size;
} LinkedStack;
void initLinkedStack(LinkedStack *stack) {
stack->top = NULL;
stack->size = 0;
}
int isEmpty(LinkedStack *stack) {
return stack->top == NULL;
}
void linkedPush(LinkedStack *stack, int value) {
StackNode *newNode = (StackNode*)malloc(sizeof(StackNode));
if (!newNode) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;
stack->size++;
printf("Pushed %d to stack\n", value);
}
int linkedPop(LinkedStack *stack) {
if (isEmpty(stack)) {
printf("Stack Underflow!\n");
return INT_MIN;
}
StackNode *temp = stack->top;
int popped = temp->data;
stack->top = stack->top->next;
free(temp);
stack->size--;
printf("Popped %d from stack\n", popped);
return popped;
}
void display(LinkedStack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty\n");
return;
}
printf("Stack elements (size=%d): ", stack->size);
StackNode *current = stack->top;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
int main() {
LinkedStack stack;
initLinkedStack(&stack);
linkedPush(&stack, 100);
linkedPush(&stack, 200);
linkedPush(&stack, 300);
display(&stack);
linkedPop(&stack);
display(&stack);
// 测试大量操作
for (int i = 0; i < 20; i++) {
linkedPush(&stack, i);
}
display(&stack);
for (int i = 0; i < 25; i++) {
linkedPop(&stack);
}
display(&stack);
return 0;
}
本文详细介绍了在C语言中实现栈的两种主要方式:基于数组的顺序栈和基于链表的链式栈。通过对比分析,我们可以得出以下结论:
栈作为基础数据结构,在编译器设计、操作系统、算法等领域有广泛应用。掌握其实现原理和特性,对于提高编程能力和理解复杂系统都有重要意义。 “`
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
开发者交流群:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/mizhinian/blog/4472985