二叉树的遍历

二叉树的遍历

说一下四个非递归遍历的思路。
先序的非递归遍历最好理解,先将根节点节点入栈,进入循环,将栈顶元素出栈,输出节点数据,然后将出栈节点右孩子入栈,再压入左孩子,这样的顺序入站之后栈顶节点就是上一个节点的左孩子。重复这个过程直到栈空遍历完成。

中序的非递归遍利用一个栈保存上一个节点,首先左子树一路走到底,遇到叶子节点之后栈顶元素弹出,然后将将弹出的节点的右子树入栈。

后序遍历用了两个栈,我们先看一下图中的二叉树
图:在这里插入图片描述
该二叉树的先序遍历为:1 2 3 4 5 6 7 8 9
后序遍历为:4 3 6 5 2 8 9 7 1
后序遍历的倒置序列是:1 7 9 8 2 5 6 3 4,仔细观察该序列就会发现它是上图中的二叉树交换左右子树之后的先序遍历。所以我们只需要将该序列倒置就能够得到后序遍历的序列里。所以后序遍历这里使用了两个栈,因为是交换左右子树所以使用反过来的先序遍历,但是不需要输出,只需要将栈一弹出的数据压入栈二。等遍历结束之后输出栈二内的数据。

层次遍历的非递归使用队列来实现代码和先序遍历差不多,先将根节点入队,取队头结点输出节点数据,将对头结点出队,然后将出队的节点的左孩子入队,在将其右孩子入队,如果画出队列中的数据情况会发现,每一层节点有从左之后在队列里,只需要一个个出队输出就可以了。

#include <iostream>
#include <stack>
#include <queue>
using namespace std;
//节点类型
struct Node
{
    int data;
    Node *lchild,*rchild;
};

//建树
void CreateTree(Node* &root)
{
    int data;
    cin>>data;
    if(data==-1)
    {
        root=nullptr;
    }
    else
    {
        root=new Node();
        root->data=data;
        CreateTree(root->lchild);
        CreateTree(root->rchild);
    }
}
//前序递归
void PreOrderWithRecursive(Node *root)
{
    if(root==nullptr)
        return;
    else
    {
        cout<<root->data<<" ";
        PreOrderWithRecursive(root->lchild);
        PreOrderWithRecursive(root->rchild);
    }
}
//中续递归
void MidOrderWithRecursive(Node *root)
{
    if(root==nullptr)
        return;
    else
    {
        MidOrderWithRecursive(root->lchild);
        cout<<root->data<<" ";
        MidOrderWithRecursive(root->rchild);
    }
}
//后续递归
void PostOrderWithRecursive(Node *root)
{
    if(root==nullptr)
        return;
    else
    {
        PostOrderWithRecursive(root->lchild);
        PostOrderWithRecursive(root->rchild);
        cout<<root->data<<" ";
    }
}

//前序非递归
void PreOrderWithOutRecursive(Node *root)
{
    stack<Node*> s;
    Node *r=root;
    while(r!=nullptr||!s.empty())
    {
        if(r)
        {
            cout<<r->data<<" ";
            s.push(r);
            r=r->lchild;
        }
        else
        {
            r=s.top();
            s.pop();
            r=r->rchild;
        }
    }
}

//中序非递归
void MidOrderWithOutRecursive(Node *root)
{
    stack<Node*> s;
    Node *p=root;
    while(p!=nullptr||!s.empty())
    {
        if(p)
        {
            s.push(p);
            p=p->lchild;
        }
        else
        {
            p=s.top();
            cout<<p->data<<" ";
            p=p->rchild;
            s.pop();
        }
    }
}

//后续非递归
void PostOrderWithOutRecursive(Node *root)
{
    stack<Node*> s1;
    stack<int> s2;
    Node *p=root;
    s1.push(p);
    while(!s1.empty())
    {
        p=s1.top();
        s2.push(p->data);
        s1.pop();
        if(p->lchild)
            s1.push(p->lchild);
        if(p->rchild)
            s1.push(p->rchild);
    }

    while(!s2.empty())
    {
        cout<<s2.top()<<" ";
        s2.pop();
    }
}

//层序
void LevelOrder(Node *root)
{
    queue<Node*> q;
    Node *p=root;
    q.push(p);
    while(!q.empty())
    {
        p=q.front();
        cout<<p->data<<" ";
        q.pop();
        if(p->lchild)
            q.push(p->lchild);
        if(p->rchild)
            q.push(p->rchild);
    }
}

int main()
{
    //1 2 3 4 -1 -1 -1 5 6 -1 -1 -1 7 8 -1 -1 9 -1 -1
    Node *root;
    cout<<"建树:";
    CreateTree(root);
    cout<<"递归前序遍历:";
    PreOrderWithRecursive(root);
    cout<<endl<<"非递归前序遍历:";
    PreOrderWithOutRecursive(root);
    cout<<endl<<"递归中序遍历:";
    MidOrderWithRecursive(root);
    cout<<endl<<"非递归中序遍历:";
    MidOrderWithOutRecursive(root);
    cout<<endl<<"递归后序遍历:";
    PostOrderWithRecursive(root);
    cout<<endl<<"非递归后序遍历:";
    PostOrderWithOutRecursive(root);
    cout<<endl<<"层序遍历:";
    LevelOrder(root);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言参考答案汇总(浙江大学城市学院) 第2周(M2) 2 20011求华氏温度100°F对应的摄氏温度。 2 20012 求华氏温度 150°F 对应的摄氏温度。 3 20013求摄氏温度26°C对应的华氏温度。 3 20015当n为152时,分别求出n的个位数字(digit1)、十位数字(digit2)和百位数字(digit3)的值。 3 20026 输入2个整数 num1 和 num2,计算并输出它们的和、差、积、商与余数。 4 第3周(M3) 5 20031 求1+2+3+......+100(调试示例error02_5) 5 20032 求m+(m+1)+(m+2)+......+100 5 20033 求1/m+1/(m+1)+1/(m+2)+......+1/n 6 20034 求1 + 1/3 + 1/5 + ......的前n项和 7 20035 求1-1/4+1/7-1/10+……的前n项之和 7 20036 输出华氏-摄氏温度转换表(改错题error02_6) 8 20038 求x的n次幂 9 20041 生成 3 的乘方表 10 20044 求100^0.5+101^0.5+……+1000^0.5 10 20053 计算物体自由下落的距离 11 20056 计算分段函数 11 20061 阶梯电价 12 20062 求m*m+1/m+(m+1)*(m+1)+1/(m+1)+(m+2)*(m+2)+1/(m+2)+......+n*n+1/n 13 20063 求1-2/3+3/5-4/7+5/9-6/11+…… 14 20064 求2^1+2^2+2^3+……+2^n 15 第4周(M4) 15 10007 显示图案 (复习printf()的字符串输出) 15 20042 生成阶乘表 16 20043 使用函数求 n! /(m!* (n-m)!) 16 20054 求平均值 17 20057 求1+1/2+1/3+......+1/n 18 20065 求0!+1!+2!+……+n! 18 40015 求最小值 19 40018 求a+aa+aaa+aa…a 20 第5周(M5) 21 30001 求一元二次方程的根 21 30002 求分段函数的值 23 30003 分类统计字符 23 30004 显示五级记分制成绩所对应的百分制成绩区间(使用switch) 24 30005 显示水果的价格(使用switch) 25 30007 求三角形的面积和周长 27 30008 计算个人所得税 28 30051 判断闰年 29 30052 统计学生平均成绩与及格人数 30 30053 分段计算水费(使用嵌套的if-else语句) 31 第6周(M6) 32 40011 求最小公倍数和最大公约数(调试示例error04_1) 32 40012 求1-1/4+1/7-1/10+1/13-1/16+…… 33 40014 求整数的位数 34 40023 换硬币 35 40024 找出各位数字的立方和等于它本身的数 36 40025 找完数(改错题error04_2) 38 40027 从高位开始逐位输出一个整数的各位数字(选作) 39 40052 判断素数 40 40053 逆序输出整数 41 40054 输出斐波那契序列 42 第7周(M7) 42 50002 使用函数判断数的符号 42 50003 使用函数求奇数和 43 50005 使用函数统计素数并求和 44 50006 使用函数统计一个整数中数字的个数 45 50007 使用函数找水仙花数 46 50009 使用函数求余弦函数的近似值 48 50052 使用函数找最大值 49 50062 使用函数输出指定范围内的 Fibonacci 数 50 50063 使用函数找出指定范围内的完数 51 第8周(M8) 52 40013 求奇数和 52 40062 求x+x*x/2!+x*x*x/3!+x*x*x*x/4!+……的值 53 50004 使用函数计算两点间的距离 54 50061 使用函数求a+aa+aaa+aa…a 55 60002 整数的十进制、八进制和十六进制表现形式 56 60003 分类统计字符 57 60006 验证歌德巴赫猜想 58 60007 使用函数输出整数的逆序数 59 60009 统计单词 60 60062 简单计算器 61

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值