C语言栈与递归的实现讲解

简介: C语言栈与递归的实现讲解

栈(Stack)是一种后进先出(LIFO,Last In First Out)的数据结构,常用于实现递归函数。递归函数通过不断地自我调用,将问题分解为更小的子问题,直到达到基本情况(终止条件),然后a从基本情况开始逐步返回结果。在递归的过程中,每个递归调用都需要保存其上下文信息(如局部变量、参数等),这些信息通常存储在栈上。

下面我们将讲解如何使用C语言实现栈,并用栈来模拟递归的过程。

栈的实现

首先,我们定义一个栈的数据结构以及基本的栈操作函数。

 

#include <stdio.h> 

 

#include <stdlib.h> 

 

#include <stdbool.h> 

 

 

 

#define MAX_STACK_SIZE 100

 

 

 

typedef struct {

 

int top;

 

int items[MAX_STACK_SIZE];

 

} Stack;

 

 

 

void initStack(Stack *s) {

 

s->top = -1;

 

}

 

 

 

bool isStackEmpty(Stack *s) {

 

return s->top == -1;

 

}

 

 

 

bool isStackFull(Stack *s) {

 

return s->top == MAX_STACK_SIZE - 1;

 

}

 

 

 

void push(Stack *s, int item) {

 

if (isStackFull(s)) {

 

printf("Stack is full.\n");

 

return;

 

}

 

s->items[++s->top] = item;

 

}

 

 

 

int pop(Stack *s) {

 

if (isStackEmpty(s)) {

 

printf("Stack is empty.\n");

 

return -1;

 

}

 

return s->items[s->top--];

 

}

 

 

 

int peek(Stack *s) {

 

if (isStackEmpty(s)) {

 

printf("Stack is empty.\n");

 

return -1;

 

}

 

return s->items[s->top];

 

}

使用栈模拟递归

假设我们要计算阶乘(factorial),通常我们会使用递归来实现。但是,我们也可以使用栈来模拟递归的过程。

阶乘的递归定义如下:

 

int factorial(int n) {

 

if (n == 0) {

 

return 1;

 

} else {

 

return n * factorial(n - 1);

 

}

 

}

现在,我们使用栈来模拟这个递归过程:

 

int factorialIterative(int n) {

 

Stack s;

 

initStack(&s);

 

int result = 1;

 

 

 

// 将参数压入栈中,模拟递归调用

 

push(&s, n);

 

 

 

while (!isStackEmpty(&s)) {

 

int current = pop(&s);

 

if (current == 0) {

 

// 基本情况,返回1

 

result *= 1;

 

} else {

 

// 递归调用模拟,将下一个子问题压入栈中

 

push(&s, current - 1);

 

result *= current;

 

}

 

}

 

 

 

return result;

 

}

在上面的代码中,我们创建了一个栈s,并将要计算的阶乘数n压入栈中。然后,我们进入一个循环,每次从栈中弹出一个数,并判断它是否为基本情况(即0)。如果是基本情况,我们直接乘以1(实际上不改变结果)。否则,我们将下一个子问题(即current - 1)压入栈中,并将当前数乘以结果。这个过程一直持续到栈为空为止,此时我们就得到了阶乘的结果。

主函数与测试

最后,我们编写一个主函数来测试上述实现:

 

int main() {

 

int n = 5;

 

printf("Factorial of %d using recursion: %d\n", n, factorial(n));

 

printf("Factorial of %d using stack simulation: %d\n", n, factorialIterative(n));

 

return 0;

 

}

请注意,上述代码是一个简单的示例,用于说明如何使用栈来模拟递归过程。在实际应用中,递归和栈的使用会更加复杂,需要根据具体的问题进行设计和实现。此外,由于栈的大小有限(在上面的示例中定义为MAX_STACK_SIZE),对于非常深的递归调用或非常大的输入数据,可能会导致栈溢出的问题。在实际应用中,需要合理设计算法和数据结构,以避免栈溢出的问题。

 

目录
相关文章
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
174 9
|
4月前
|
机器学习/深度学习 C语言
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
【8月更文挑战第5天】本篇文章用C语言采用多文件编写实现了一个基础的扫雷游戏(附源码),并讲解了关于函数递归的基础概念及其相对应的习题练习(附源码)
46 1
九/十:《初学C语言》— 扫雷游戏实现和函数递归基础
|
21天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
43 5
|
2月前
|
机器学习/深度学习 C语言
【c语言】一篇文章搞懂函数递归
本文详细介绍了函数递归的概念、思想及其限制条件,并通过求阶乘、打印整数每一位和求斐波那契数等实例,展示了递归的应用。递归的核心在于将大问题分解为小问题,但需注意递归可能导致效率低下和栈溢出的问题。文章最后总结了递归的优缺点,提醒读者在实际编程中合理使用递归。
69 7
|
2月前
|
C语言
c语言回顾-函数递归(上)
c语言回顾-函数递归(上)
41 2
|
2月前
|
C语言
数组栈的实现(C语言描述)
本文介绍了如何在C语言中使用数组来实现栈的数据结构,包括栈的创建、入栈、出栈、获取栈顶元素、检查栈是否为空、获取栈的大小以及销毁栈等操作,并提供了相应的函数实现。
40 1
|
2月前
|
C语言
c语言回顾-函数递归(下)
c语言回顾-函数递归(下)
41 0
|
3月前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
475 8
|
3月前
|
存储 C语言
数据结构基础详解(C语言): 栈与队列的详解附完整代码
栈是一种仅允许在一端进行插入和删除操作的线性表,常用于解决括号匹配、函数调用等问题。栈分为顺序栈和链栈,顺序栈使用数组存储,链栈基于单链表实现。栈的主要操作包括初始化、销毁、入栈、出栈等。栈的应用广泛,如表达式求值、递归等场景。栈的顺序存储结构由数组和栈顶指针构成,链栈则基于单链表的头插法实现。
499 3
|
4月前
|
机器学习/深度学习 C语言
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)
要保持最小的步数,每一次汉诺塔问题(无论是最初还是递归过程中的),如果此时初始柱盘子数为偶数,我们第一步是把最上面的盘子移动到中转柱,如果为奇数,我们第一步则是将其移动到目标柱。
100 0
【C语言篇】递归详细介绍(基础概念习题及汉诺塔等进阶问题)