二叉树之递归实现前、中、后序遍历

1,020 阅读2分钟

储备知识

什么是二叉树

引用维基百科的解释:

二叉树(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒。

image.png

前、中、后序遍历是什么

通俗的说就是对于每一棵树,它树顶的位置在两个孩子的前面为前序遍历、中间为中序遍历、后面为后序遍历(孩子的顺序一定是左孩子在右孩子前面)。如上面的二叉树,对于 ABC 这个小树来说: ABC 为 前序遍历,BAC 为中序遍历,BCA 为后序遍历。

二叉树的实现方式
  • 链式存储 通过链表结构来实现。基于链表结构,可以从每个几点找到其子节点。大部分二叉树都是通过链表来实现的。

  • 顺序存储 通过数组的方式来实现。只适用于完全二叉树。父节点与子节点的索引关系为:

leftChildrenIndex=2fatherIndex+1;leftChildrenIndex = 2 * fatherIndex + 1;
rightChildrenIndex=2fatherIndex+2;rightChildrenIndex = 2 * fatherIndex + 2;

JavaScript递归实现

前序遍历
function pre(tree, fatherIndex) {
  if (!tree[fatherIndex]) { 
    return;
  }
  console.log(tree[fatherIndex]);
  let leftChildrenIndex = 2 * fatherIndex + 1; 
  let rightChildrenIndex = 2 * fatherIndex + 2;
  pre(tree, leftChildrenIndex);
  pre(tree, rightChildrenIndex);
}

中序遍历
function middle(tree, fatherIndex) {
  if (!tree[fatherIndex]) { 
    return;
  } 
  let leftChildrenIndex = 2 * fatherIndex + 1; 
  let rightChildrenIndex = 2 * fatherIndex + 2;
  middle(tree, leftChildrenIndex);
  console.log(tree[fatherIndex]);
  middle(tree, rightChildrenIndex);
}
后序遍历
function next(tree, fatherIndex) {
  if (!tree[fatherIndex]) { 
    return;
  } 
  let leftChildrenIndex = 2 * fatherIndex + 1; 
  let rightChildrenIndex = 2 * fatherIndex + 2;
  next(tree, leftChildrenIndex);
  next(tree, rightChildrenIndex);
  console.log(tree[fatherIndex]);
}

递归序

从上面的前、中、后遍历函数可以看出,递归模式写法完全一致,只是 console.log 的位置不一样,如此就实现了三种顺序的打印。这是为什么呢?答案就是递归序。 递归序,顾名思义就是递归的顺序。

那么是怎么用到递归序来解决前、中、后序遍历的呢?举个例,查看下图:

image.png

根据代码可知每个节点都会经过3次,而在这三次中,哪一次打印会决定是什么遍历;经过的线路如下:

image.png

这里每个节点会经过三次是因为函数在函数体内,调用了自己两次。