二叉树(链表实现)–前序、中序、后序、层序遍历
我们把树简单的画作上图中的样子,由一个根节点、一个左子树、一个右子树组成,那么按照根节点什么时候被访问,我们可以把二叉树的遍历分为以下三种方式:
1.前序遍历;
先访问根结点,然后再访问左子树,最后访问右子树
2.中序遍历;
先访问左子树,中间访问根节点,最后访问右子树
3.后序遍历;
先访问左子树,再访问右子树,最后访问根节点
如果我们分别对下面的树使用三种遍历方式进行遍历,得到的结果如下:
前序遍历
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);
}
层序遍历
所谓的层序遍历,就是从根节点(第一层)开始,依次向下,获取每一层所有结点的值,有二叉树如下:
那么层序遍历的结果是:EBGADFHC
public Queue<Key> layerErgodic():使用层序遍历,获取整个树中的所有键
实现步骤:
1.创建队列,存储每一层的结点;
2.使用循环从队列中弹出一个结点:
2.1获取当前结点的key;
2.2如果当前结点的左子结点不为空,则把左子结点放入到队列中
2.3如果当前结点的右子结点不为空,则把右子结点放入到队列中
代码:
// 使用层序遍历,获取整个树中的所有键
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;
}