二叉树的初始化以及二叉树的前序遍历,中序遍历,后序遍历的递归和非递归算法

前几天回家过中秋,我一直在想二叉树的3种遍历方法,今天在图书馆自习的时候想出来了,现在我跟大家先分享一下二叉树的3种遍历的递归算法,递归算法很简单,关键在于理解二叉树遍历的核心思想,话不多说,我们直接看代码:

#include<iostream>
#include<queue> 
using namespace std;
struct TreeNode{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x):val(x),left(NULL),right(NULL){}//初始化列表 
};
/*二叉树的前序遍历 
根左右 
*/

void PreOrder(TreeNode* t) {
	if(t==NULL)
	return;
	cout<<t->val<<" ";
	PreOrder(t->left);
	PreOrder(t->right);
}
/*二叉树的中序遍历
左根右 
*/ 
void InOrder(TreeNode* t){
	if(t==NULL)
	return;
	InOrder(t->left);
	cout<<t->val<<" "; 
	InOrder(t->right);
} 
/*二叉树的后序遍历
左右根 
*/
void LastOrder(TreeNode* t){
	if(t==NULL)
	return;
	LastOrder(t->left);
	LastOrder(t->right);
	cout<<t->val<<" ";	
} 
//初始化一棵二叉树 
TreeNode* InitBTree(int a[],int size){
	if(size<1){
		return NULL;
	}
	//动态申请size大小的指针数组
	 TreeNode **nodes=new TreeNode*[size];
	 //将int数组转换为TreeNode结点
	  for(int i=0;i<size;i++){
	  	if(a[i]==0){
	  		nodes[i]=NULL;
		  }
		  else{
		  	nodes[i]=new TreeNode(a[i]);
		  }
	  }
	  queue<TreeNode*> nodeQueue;
	nodeQueue.push(nodes[0]);
 
	TreeNode *node;
	int index = 1;
	while (index < size)
	{
		node = nodeQueue.front();
		nodeQueue.pop();
		nodeQueue.push(nodes[index++]);
		node->left = nodeQueue.back();
		nodeQueue.push(nodes[index++]);
		node->right = nodeQueue.back();
	}
	  return nodes[0];
}
int main(){
	int nums[]={1,2,3,4,0,5,6,0,7};
	TreeNode *root=InitBTree(nums,9);
	PreOrder(root);
	cout<<endl;
	InOrder(root);
	cout<<endl;
	LastOrder(root);
	return 0;
}

我先说一下nums这个数组,它里面的元素是根据完全二叉树构造的,0代表这个结点为null。其实难点还是在于二叉树的初始化,我是用队列来完成的,主要算法是:先将根结点入队,然后将它的左孩子和右孩子依次入队。然后根结点出队,队首变成了根结点的左孩子(如果存在),然后反复递归,最终把nums数组里面的元素变成了一棵二叉树。
上面是我写的二叉树遍历基于递归的算法,非递归算法的话,我想过几天再写,你们如果对我写的代码有什么改进意见的话,可以私聊我博客,我们共同进步,我几乎天天都会去看博客。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 中序遍历递归算法: 1. 如果树为空,则返回。 2. 对根节点的左子树进行中序遍历。 3. 访问根节点。 4. 对根节点的右子树进行中序遍历中序遍历非递归算法: 1. 初始化一个栈,将根节点入栈。 2. 如果栈不为空,执行以下操作: a. 将栈顶节点弹出并访问。 b. 如果栈顶节点的右子树不为空,将右子树入栈。 c. 如果栈顶节点的左子树不为空,将左子树入栈。 后序遍历递归算法: 1. 如果树为空,则返回。 2. 对根节点的左子树进行后序遍历。 3. 对根节点的右子树进行后序遍历。 4. 访问根节点。 后序遍历非递归算法: 1. 初始化两个栈,将根节点入栈1。 2. 如果栈1不为空,执行以下操作: a. 将栈1顶部节点弹出并压入栈2。 b. 如果栈1顶部节点的左子树不为空,将左子树入栈1。 c. 如果栈1顶部节点的右子树不为空,将右子树入栈1。 3. 当栈1为空时,依次弹出栈2中的节点并访问。 ### 回答2: 二叉树一种常见的数据结构,在计算机科学中应用广泛。在对二叉树进行遍历时,有三种方式:前序遍历(先遍历根节点,然后遍历左子树和右子树)、中序遍历(先遍历左子树,然后遍历根节点和右子树)和后序遍历(先遍历左子树和右子树,然后遍历根节点)。对于一棵二叉树,它们的遍历序列各不相同,因此在编写程序时需要对它们进行分类讨论。 1. 中序遍历递归算法 中序遍历递归算法相对简单,只需按照左子树-根节点-右子树的顺序遍历即可。具体实现如下: ``` void inorderTraversal(TreeNode* root) { if (root == nullptr) return; inorderTraversal(root->left); // 处理根节点 cout << root->val << " "; inorderTraversal(root->right); } ``` 2. 中序遍历非递归算法 采用非递归算法实现中序遍历时,需要借助栈来记录遍历过程中的节点信息。具体实现如下: ``` void inorderTraversal(TreeNode* root) { stack<TreeNode*> stk; while (root != nullptr || !stk.empty()) { while (root != nullptr) { stk.push(root); root = root->left; } root = stk.top(); stk.pop(); // 处理根节点 cout << root->val << " "; root = root->right; } } ``` 3. 后序遍历递归算法 后序遍历递归算法也相对简单,只需按照左子树-右子树-根节点的顺序遍历即可。具体实现如下: ``` void postorderTraversal(TreeNode* root) { if (root == nullptr) return; postorderTraversal(root->left); postorderTraversal(root->right); // 处理根节点 cout << root->val << " "; } ``` 4. 后序遍历非递归算法 采用非递归算法实现后序遍历时,需要借助栈来记录遍历过程中的节点信息。具体实现如下: ``` void postorderTraversal(TreeNode* root) { stack<TreeNode*> stk; TreeNode* prev = nullptr; while (root != nullptr || !stk.empty()) { while (root != nullptr) { stk.push(root); root = root->left; } root = stk.top(); if (root->right == nullptr || root->right == prev) { stk.pop(); // 处理根节点 cout << root->val << " "; prev = root; root = nullptr; } else { root = root->right; } } } ``` 在以上算法中,递归算法较为简单易懂,但当二叉树较大时,容易造成栈溢出;非递归算法节省了栈空间,但代码相对复杂。在实际应用中,应根据具体情况选择合适的算法。 ### 回答3: 二叉树一种树状数据结构,由一个根节点和每个节点最多有两个子节点组成。二叉树遍历是指按照某种次序依次访问二叉树中的所有节点。其中,中序遍历是指先访问左子树,再访问根节点,最后访问右子树;后序遍历是指先访问左子树,再访问右子树,最后访问根节点。 在编写程序实现二叉树中序遍历后序遍历时,可采用递归非递归算法两种方法进行。 递归算法中序遍历递归算法 1. 如果根节点为NULL,返回 2. 中序遍历根节点的左子树 3. 访问根节点 4. 中序遍历根节点的右子树 代码如下: ``` void inorderTraversal(TreeNode* root) { if(root == NULL) return; inorderTraversal(root->left); cout<<root->val<<" "; inorderTraversal(root->right); } ``` 后序遍历递归算法 1. 如果根节点为NULL,返回 2. 后序遍历根节点的左子树 3. 后序遍历根节点的右子树 4. 访问根节点 代码如下: ``` void postorderTraversal(TreeNode* root) { if(root == NULL) return; postorderTraversal(root->left); postorderTraversal(root->right); cout<<root->val<<" "; } ``` 非递归算法中序遍历非递归算法 1. 将根节点入栈 2. 当栈不为空时,弹出栈顶元素 3. 如果弹出的元素不为空,将其右子节点入栈 4. 如果弹出的元素为空,继续弹出栈顶元素并访问 5. 如果弹出的元素不为空,将其左子节点入栈 代码如下: ``` vector<int> inorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; while(root || !stk.empty()) { while(root) { stk.push(root); root = root->left; } root = stk.top(); stk.pop(); res.push_back(root->val); root = root->right; } return res; } ``` 后序遍历非递归算法 1. 将根节点入栈 2. 当栈不为空时,弹出栈顶元素 3. 将弹出的元素加入结果列表 4. 如果弹出的元素左子节点不为空,将其左子节点入栈 5. 如果弹出的元素右子节点不为空,将其右子节点入栈 6. 将结果列表反转,得到后序遍历结果 代码如下: ``` vector<int> postorderTraversal(TreeNode* root) { vector<int> res; stack<TreeNode*> stk; while(root || !stk.empty()) { while(root) { stk.push(root); res.insert(res.begin(), root->val); root = root->right; } root = stk.top(); stk.pop(); root = root->left; } return res; } ``` 以上就是关于二叉树中序遍历后序遍历递归非递归算法的详细介绍。在编写程序时,需要注意遍历时的访问顺序以及栈的使用。通过使用不同的算法,可以达到不同的时间和空间复杂度,因此需要根据具体问题场景进行选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值