您的位置:首页 > 其它

树的递归与非递归实现

2016-06-13 15:35 337 查看
二叉树中最重要的操作为遍历:

前序遍历:先访问根节点,再访问左子树,最后访问右子树

中序遍历:先访问左子树,再访问根节点,最后访问右子树

后序遍历:先访问左子树,在访问右子树,最后访问根节点

这三种遍历方式都有递归和非递归的实现方式。

二叉树的建立,首先对树进行扩展,扩展二叉树就可以做到一个遍历序列确定一棵二叉树了。

<pre name="code" class="cpp">
#include <iostream>
#include<stack>

using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
string tree("1!2!4!#!#!5!#!#!3!6!#!#!7!#!#!");
int index=0;
//函数创建二叉树,根据给定的序列创建二叉树。每个节点值使用!隔开。
void creatree(TreeNode** root){
int result=0;
if(tree[index]=='#'){
*root=NULL;
index=index+2;
return;
}

while(tree[index]!='!')//将字符串转为数字
{   result=result*10+tree[index]-'0';
++index;
}
++index;
*root=new TreeNode(result);
creatree(&((*root)->left));
creatree(&((*root)->right));
}
//前序遍历的递归实现
void pretrave(TreeNode* root){
if(root==NULL)
return;
cout<<root->val<<' ';
pretrave(root->left);
pretrave(root->right);
}
//前序遍历的非递归实现
/*主要思想:1、首先申请一个栈stack
2、将头结点head压入栈
3、从栈中弹出一个节点,若该节点的右孩子不为空,则将右孩子压入栈中
若该节点的左孩子不为空,将左孩子压入栈中。
4、不断重复步骤3直到栈为空*/
void non_pretrave(TreeNode *root){
if(root==NULL)
return;
stack<TreeNode*> buc;
buc.push(root);
while(!buc.empty()){
TreeNode *temp=buc.top();
cout<<temp->val<<' ';
buc.pop();
if(temp->right!=NULL){
buc.push(temp->right);
}
if(temp->left!=NULL){
buc.push(temp->left);
}
}
return;
}

//中序遍历的递归实现
void midtrave(TreeNode* root){
if(root==NULL)
return;

midtrave(root->left);
cout<<root->val<<' ';
midtrave(root->right);
}
//非递归实现中序遍历
/*1、建立一个栈
2、建立一个变量cur,令头结点等于cur,将cur压入栈中,然后不断的
cur=cur->left压入栈中,直到cur为空
3、弹出一个节点计为node,cur=node->right,重复步骤2直到栈为空
*/
void non_midtrave(TreeNode* root){
if(root==NULL)
return;
stack<TreeNode*> st;
TreeNode* cur=root;
st.push(cur);
while(cur->left){
cur=cur->left;
st.push(cur);
}
while(!st.empty()){

TreeNode* node=st.top();
st.pop();
cout<<node->val<<' ';
cur=node->right;
while(cur){
st.push(cur);
cur=cur->left;

}

}
}

//后序遍历的递归实现
void posttrave(TreeNode* root){
if(root==NULL)
return;

posttrave(root->left);
posttrave(root->right);
cout<<root->val<<' ';
}
//非递归实现后续遍历
/*1、申请两个栈,记为S1,S2
2、将头结点压入栈中,结点弹出,将结点压入S2中,
将结点的左孩子和右孩子依次压入S1中。
3、不断的重复步骤2,直到S1为空,S2中存放的即为后序遍历的节点顺序*/
void non_posttrave(TreeNode* root){
if(root==NULL)
return ;
stack<TreeNode*> s1,s2;
TreeNode* cur=root;
s1.push(cur);
while(!s1.empty()){
TreeNode *temp=s1.top();
s1.pop();
s2.push(temp);
if(temp->left!=NULL)
s1.push(temp->left);
if(temp->right!=NULL)
s1.push(temp->right);
}
while(!s2.empty()){
TreeNode* node=s2.top();
s2.pop();
cout<<node->val<<' ' ;

}
}
int main()
{    TreeNode*root;
root=NULL;
creatree(&root);
cout<<"递归实现前序遍历: ";
pretrave(root);cout<<endl;
cout<<"非递归实现前序遍历: ";
non_pretrave(root);

cout<<endl;
cout<<"递归实现中序遍历: ";
midtrave(root);
cout<<endl;
cout<<"非递归实现中序遍历: ";
non_midtrave(root);
cout<<endl;
cout<<"递归实现后序遍历: ";
posttrave(root);
cout<<endl;
cout<<"非递归实现后序遍历: ";
non_posttrave(root);
return 0;
}



运行结果:



               
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: