栈和队列的应用——二叉树的深度遍历和广度遍历

还是昨天面试的问题,问完栈和队列,说栈和队列的应用,当时就想起了括号的匹配,,没想到二叉树的深度遍历和广度遍历,这两种遍历方式分别对应的就是栈和队列的一个应用。

1. 深度优先遍历

1.1 定义

深度优先遍历:对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。深度优先遍历可以细分为先序遍历、中序遍历、后序遍历。具体说明如下:

  • 先序遍历:对任一子树,先访问根,然后遍历其左子树,最后遍历其右子树。
  • 中序遍历:对任一子树,先遍历其左子树,然后访问根,最后遍历其右子树。
  • 后序遍历:对任一子树,先遍历其左子树,然后遍历其右子树,最后访问根。
1.2 实现

因为深度优先搜索算法是先访问根节点,接着遍历左子树再遍历右子树。因为栈是后进先出的结构,先将右子树压栈,再将左子树压栈,这样左子树就位于栈顶,可以保证先遍历左子树再遍历右子树。

void depthFirstTravel(Node* root){
    stack<Node *> nodeStack; 
    nodeStack.push(root);
    Node *node;
    while(!nodeStack.empty()){
        node = nodeStack.top();
        cout << node->key << endl;
        nodeStack.pop();
        if(node->rchild){
            nodeStack.push(node->rchild);
        }
        if(node->lchild){
            nodeStack.push(node->lchild);
        }
    }
}

2. 广度优先遍历

2.1 定义

从根节点开始,沿着树的宽度遍历树的节点,直到所有节点都被遍历完为止。

2.2 实现

因为是一层一层遍历的,所以使用队列这种数据结构,先将一层节点放到队列中,当遍历完当前这一层后,再分别出队列,同时遍历当前节点的子节点,达到一层一层遍历的目的。若使用,压入第二层时,出栈就无法按照正常顺序输出了。你品,你细品。

void breadthFirstTravel(Node* root){
queue<Node *> nodeQueue;
    nodeQueue.push(root);
    Node *node;
    while(!nodeQueue.empty()){
        node = nodeQueue.front();
        nodeQueue.pop();
        cout << node->key << endl;
        if(node->lchild){
            nodeQueue.push(node->lchild);
        }
        if(node->rchild){
            nodeQueue.push(node->rchild);
        }
    }
}

3. 完整实现

以下图的二叉树为例。

在这里插入图片描述

二叉树节点定义:

struct STreeNode
{
    char key;
    pSTreeNode lchild;
    pSTreeNode rchild;

    STreeNode(char Value)
    {
        key = Value;
        lchild = NULL;
        rchild = NULL;
    }
};
#include <iostream>
#include <stack>
#include <queue>

using namespace std;

int main()
{
    Node *root = new Node('A');
    root->lchild = new Node('B');
    root->rchild = new Node('G');
    Node *p = root->lchild;
    Node *q = root->rchild;
    p->lchild = new Node('C');
    p->rchild = new Node('D');
    p = p->rchild;
    p->lchild = new Node('E');
    p->rchild = new Node('F');
    q->lchild = new Node('H');
    q->rchild = new Node('I');
    cout << "depthFirstTravel is: " << endl;
    depthFirstTravel(root);
    cout << endl;
    cout << "breadthFirstTravel is: " << endl;
    breadthFirstTravel(root);
    cout << endl;
    system("pause");
    return 0;
}

// 结果
// depthFirstTravel is:
// A B C D E F G H I
// breadthFirstTravel is:
// A B G C D H I E F

参考

[1] 二叉树的深度遍历和广度遍历
[2] 二叉树的深度优先遍历和广度优先遍历

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值