二叉树(链表实现)--前序、中序、后序、层序遍历

二叉树(链表实现)–前序、中序、后序、层序遍历

​	  										[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIrZnBJz-1627224172302)(E:\personal\Node\数据结构与算法\笔记\assets\image22.png)]

​ 我们把树简单的画作上图中的样子,由一个根节点、一个左子树、一个右子树组成,那么按照根节点什么时候被访问,我们可以把二叉树的遍历分为以下三种方式:

1.前序遍历;

​ 先访问根结点,然后再访问左子树,最后访问右子树

2.中序遍历;

​ 先访问左子树,中间访问根节点,最后访问右子树

3.后序遍历;

​ 先访问左子树,再访问右子树,最后访问根节点

如果我们分别对下面的树使用三种遍历方式进行遍历,得到的结果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9pDZcfsM-1627224172305)(E:\personal\Node\数据结构与算法\笔记\assets\image23.png)]

前序遍历

public Queue<Key> preErgodic():使用前序遍历,获取整个树中的所有键

private void preErgodic(Node x,Queue<Key> keys):使用前序遍历,把指定树x中的所有键放入到keys队列中

实现过程中,我们通过前序遍历,把,把每个结点的键取出,放入到队列中返回即可。

实现步骤:

1.把当前结点的key放入到队列中;

2.找到当前结点的左子树,如果不为空,递归遍历左子树

3.找到当前结点的右子树,如果不为空,递归遍历右子树

代码:

// 使用前序遍历(根->左->右),获取整个树中的所有键
public Queue<Key> preErgodic() {
    Queue<Key> keys = new Queue<>();
    preErgodic(root, keys);
    return keys;
}
// 使用前序遍历(根->左->右),把指定树x中的所有键放入到keys队
private void preErgodic(Node x, Queue
    // 如果x结点为空,结束遍历
    if (x == null) {
        return;
    }
    // 如果x结点不为空,进行前序遍历(根->左->右)
    // 将x结点的key值存入队列中
    keys.enqueue(x.key);
    // 递归调用前序遍历,保存左子树
    if (x.left != null) {
        preErgodic(x.left, keys);
    }
    // 递归调用前序遍历,保存右子树
    if (x.right != null) {
        preErgodic(x.right, keys);
    }
}
中序遍历

public Queue midErgodic():使用中序遍历,获取整个树中的所有键

private void midErgodic(Node x,Queue keys):使用中序遍历,把指定树x中的所有键放入到keys队列中

实现步骤:

1.找到当前结点的左子树,如果不为空,递归遍历左子树

2.把当前结点的key放入到队列中;

3.找到当前结点的右子树,如果不为空,递归遍历右子树

代码:

// 使用中序遍历(左->根->右),获取整个树中的所有键
public Queue<Key> midErgodic() {
    Queue<Key> keys = new Queue<>();
    midErgodic(root, keys);
    return keys;
}
// 使用中序遍历(左->根->右),把指定树x中的所有键放入到keys队列中
private void midErgodic(Node x, Queue<Key> keys) {
    // 如果x结点为null,结束遍历
    if (x == null) {
        return;
    }
    // 如果x结点为空,进行中序遍历(左->根->右)
    // 递归遍历左子树,将key存入队列中
    if (x.left != null) {
        midErgodic(x.left, keys);
    }
    // 将x结点的key值存入队列中
    keys.enqueue(x.key);
    // 递归遍历右子树,将key存入队列中
    if (x.right != null) {
        midErgodic(x.right, keys);
    }
}
后序遍历

public Queue<Key> afterErgodic():使用后序遍历,获取整个树中的所有键

private void afterErgodic(Node x,Queue<Key> keys):使用后序遍历,把指定树x中的所有键放入到keys队列中

实现步骤:

1.找到当前结点的左子树,如果不为空,递归遍历左子树

2.找到当前结点的右子树,如果不为空,递归遍历右子树

3.把当前结点的key放入到队列中;

代码:

// 使用后序遍历(左->右->根),获取整个树中的所有键
public Queue<Key> afterErgodic() {
    Queue<Key> keys = new Queue<>();
    afterErgodic(root, keys);
    return keys;
}
// 使用后序遍历(左->右->根),把指定树x中的所有键放入到keys队列中
private void afterErgodic(Node x, Queue<Key> keys) {
    // 如果x结点为null,结束遍历
    if (x == null) {
        return;
    }
    // 如果x结点为空,进行中序遍历(左->右->根)
    // 递归遍历左子树,将key存入队列中
    if (x.left != null) {
        afterErgodic(x.left, keys);
    }
    // 递归遍历右子树,将key存入队列中
    if (x.right != null) {
        afterErgodic(x.right, keys);
    }
    // 将x结点的key值存入队列中
    keys.enqueue(x.key);
}
层序遍历

​ 所谓的层序遍历,就是从根节点(第一层)开始,依次向下,获取每一层所有结点的值,有二叉树如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ITnGSgE6-1627224172306)(E:\personal\Node\数据结构与算法\笔记\assets\image24.png)]

那么层序遍历的结果是:EBGADFHC

public Queue<Key> layerErgodic():使用层序遍历,获取整个树中的所有键

实现步骤:

1.创建队列,存储每一层的结点;

2.使用循环从队列中弹出一个结点:

2.1获取当前结点的key;

2.2如果当前结点的左子结点不为空,则把左子结点放入到队列中

2.3如果当前结点的右子结点不为空,则把右子结点放入到队列中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzgSPvIP-1627224172308)(E:\personal\Node\数据结构与算法\笔记\assets\image25.png)]

代码:

// 使用层序遍历,获取整个树中的所有键
public Queue<Key> layerErgodic() {
    // 存放层序遍历的结果key
    Queue<Key> keys = new Queue<>();
    // 存放按照层序遍历的要求,遍历的所有的结点
    Queue<Node> nodes = new Queue<>();
    if (root == null) { // 判断树是否为空,不为空,将根结点存入nodes队列中
        return null;
    }
    nodes.enqueue(root);
    // 循环队列,完成层序遍历
    while (!nodes.isEmpty()) {
        // 从队列中取出一个结点,并将key存入keys队列中
        Node currNode = nodes.dequeue();
        keys.enqueue(currNode.key);
        // 如果当前结点的左结点不为空,将左结点存入nodes队列
        if (currNode.left != null) {
            nodes.enqueue(currNode.left);
        }
        // 如果当前结点的右结点不为空,将左结点存入nodes队列
        if (currNode.right != null) {
            nodes.enqueue(currNode.right);
        }
    }
    return keys;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农村小白i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值