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

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

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
    评论
好的,我可以为您解答这个问题。 首先,我们需要先定义二叉树的结构体: ```c typedef struct BinaryTree { int data; struct BinaryTree* left; struct BinaryTree* right; } BinaryTreeNode; ``` 接下来,我们可以先实现深度优先遍历(DFS)来计算二叉树深度。具体实现方式可以使用递归或栈来实现。下面是使用递归的实现方式: ```c int maxDepth(BinaryTreeNode* root) { if (root == NULL) { // 如果当前节点为空,则返回0 return 0; } int leftDepth = maxDepth(root->left); // 递归遍历左子树 int rightDepth = maxDepth(root->right); // 递归遍历右子树 return fmax(leftDepth, rightDepth) + 1; // 返回左右子树深度的最大值 + 1(加1表示当前节点的深度) } ``` 接下来,我们可以实现广度优先遍历(BFS)来计算二叉树深度。具体实现方式可以使用队列来实现。下面是使用队列的实现方式: ```c int maxDepth(BinaryTreeNode* root) { if (root == NULL) { // 如果当前节点为空,则返回0 return 0; } int depth = 0; Queue* queue = createQueue(); // 创建队列 enqueue(queue, root); // 根节点入队 while (!isEmpty(queue)) { // 队列不为空时 int size = getSize(queue); // 获取队列大小 for (int i = 0; i < size; i++) { BinaryTreeNode* node = dequeue(queue); // 出队 if (node->left != NULL) { enqueue(queue, node->left); // 左子节点入队 } if (node->right != NULL) { enqueue(queue, node->right); // 右子节点入队 } } depth++; // 遍历完一层,深度+1 } return depth; } ``` 以上就是使用 C 语言实现二叉树深度计算的方法,希望能对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值