c++显式栈实现递归介绍

 更新时间:2022年01月06日 16:50:39   作者:qhh_enen  
大家好,本篇文章主要讲的是c++显式栈实现递归介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

前言

在大学的课上老师有教过,也就是用循环来实现递归,现在自己回顾一下并且做一下记录。

1. 递归

假设有函数A, 和函数B, 函数B是一个递归函数, 函数A调用函数B。
这个递归的过程分为:

函数A调用函数B,函数A将数据传给函数B。此时进入到函数B内部,函数B通过传参拿到函数A传过来的数据。执行本次调用的操作将新的数据作为参数传入函数B(递归过程, 内部再次执行2~3步骤,以此类推)。退出递归结束。

2. 显式栈实现的思路

由上面的过程可以不难看出,递归的过程遵循 后进后出 这样的一个规律。那么就很容易联想到具有同样特征的栈这样一个数据结构。这里给出显式栈实现递归的思路:
假设已经申请了一个stack的容器,

首先将初始数据压栈,这个类似于递归过程中的函数A最开始调用函数B时将数据传入的操作。接下来是循环操作,条件是true,也就是死循环, 这个类似于函数B内部一直递归调用,至于什么时候结束取决于什么时候遇到递归出口;在这个死循环里应该在每次循环时进行一次条件判定,这个条件判定相当于递归函数中决定什么时候返回的条件判定;接下来进到循环内部,首先取栈顶数据出来,这类似函数B内部取到了传参执行 本次的循环的关键操作,处理数据的任务将新的数据压栈,这部分相当于将新的数据作为参数传入函数B如果触发了循环退出条件,则退出循环

3. 代码解析

上面说了具体思路,现在用代码来说明,首先上递归的写法, 用遍历二叉树作为例子。

#include<iostream>
using namespace std;
class Node
{
public:
	int value;
	Node* left_child;
	Node* right_child;
	Node(int data)
	{
		this->data = data;
		this->left_child = nullptr;
		this->right_child = nullptr;
	}
};

void B(Node* node)
{
	//这个时候已经经历了步骤2, 函数B拿到了数据root
	// 步骤3,执行本次递归调用的关键操作
	cout << node->data<< endl; 
	// 步骤4,拿到新的数据root->left_child和root->right_child
	//调用函数B
	if (node->left_child) B(node->left_child);
	if (node->right_child) B(node->right_child);
	//步骤5,递归结束
}

void A()
{
	Node root(10);  //模拟一颗树
	B(&root); //步骤1,传参
}

int main()
{
	A();
}
以上步骤3和步骤4的顺序不是固定的,他们顺序的不同各自构成了不同的树遍历方法(先序,中序,后序遍历)。接下来是显式栈实现的写法
#include<iostream>
#include<stack>
using namespace std;
class Node
{
public:
	int value;
	Node* left_child;
	Node* right_child;
	Node(int data)
	{
		this->data = data;
		this->left_child = nullptr;
		this->right_child = nullptr;
	}
};

int main()
{
	Node root(10);  //模拟一颗树
	stack<Node*> m_stack;
	m_stack.push(&root); //步骤1,将根节点压栈, 相当于函数A调用函数B时传参
	while(true)
	{
		if (m_stack.empty())
		{
			break; 
			//这里相当于步骤5,判定循环结束条件, 也可以写到while条件上
			//为了思路更清晰,所以写在循环里面,也更好跟递归版本进行比较
		}
		//步骤2,取栈顶元素
		Node* current_node = m_stack.top();
		m_stack.pop();
		//步骤3,执行本次循环的关键操作
		cout << current_node->data<< endl;
		//步骤4, 拿到新的数据并且压栈
		if (current_node->left_child)
			m_stack.push(current_node->left_child);
		if (current_node->right_child)
			m_stack.push(current_node->right_child);
	}
}
显式栈实现的版本里,有一个细节就是取完栈顶数据之后需要将栈顶的数据出栈,这样才能使用栈是否空来判断递归出口。

到此这篇关于c++显式栈实现递归介绍的文章就介绍到这了,更多相关c++递归内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Qt 中开启线程的多种方式小结

    Qt 中开启线程的多种方式小结

    本篇文章就来整理一下 Qt 中使用线程的五种方式,方便后期回顾。前面两种比较简单,一笔带过了,主要介绍后面三种,感兴趣的朋友跟随小编一起看看吧
    2021-09-09
  • 如何在C++中调用python代码你知道吗

    如何在C++中调用python代码你知道吗

    这篇文章主要为大家介绍了C++中调用python代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C++Primer笔记之顺序容器的使用详解

    C++Primer笔记之顺序容器的使用详解

    本篇文章对C++Primer 顺序容器的使用进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • C语言格式输出二进制的2种方法总结

    C语言格式输出二进制的2种方法总结

    众所周知C中以八进制,十进制和十六进制都可以通过%o,%d和%x轻松实现,然而唯独没有提供二进制输出的快速方式,下面这篇文章主要给大家介绍了关于C语言格式输出二进制的2种方法,需要的朋友可以参考下
    2022-08-08
  • C++应用实现简易五子棋游戏

    C++应用实现简易五子棋游戏

    这篇文章主要为大家详细介绍了C++应用实现简易五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++的继承和派生你了解吗

    C++的继承和派生你了解吗

    这篇文章主要为大家详细介绍了C++继承和派生,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • c语言解析bmp图片的实例

    c语言解析bmp图片的实例

    下面小编就为大家带来一篇c语言解析bmp图片的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • C++算法之在无序数组中选择第k小个数的实现方法

    C++算法之在无序数组中选择第k小个数的实现方法

    这篇文章主要介绍了C++算法之在无序数组中选择第k小个数的实现方法,涉及C++数组的遍历、判断、运算等相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • C++的数据类型你真的了解吗

    C++的数据类型你真的了解吗

    这篇文章主要为大家详细介绍了C++的数据类型,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • C语言实现简单酒店管理系统

    C语言实现简单酒店管理系统

    这篇文章主要为大家详细介绍了C语言实现简单酒店管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论