树的递归与非递归实现

二叉树中最重要的操作为遍历:

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

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

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

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

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

<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;
}


 运行结果: 


               



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值