二叉树(英语:Binary tree)是每个节点最多只有两个分支(即不存在分支度大于2的节点)的树结构。通常分支被称作“左子树”或“右子树”。二叉树的分支具有左右次序,不能随意颠倒。
这是维基百科给的定义。
如上图就是一个二叉树,二叉树的每个节点最多只有两个分支,所以第n
层最多2^(n - 1)
个节点,而k
层总共最多有2^(k + 1) - 1
个节点
二叉树的遍历分为三种
- 前序遍历
- 中序遍历
- 后序遍历
首先要知道,所谓的前序
,中序
,后序
是什么意思?他们是指在遍历过程中中间节点的结果收集或者处理顺序。每次都是从根节点开始扫描,或者说从中间的节点开始扫描。如果先收集中间节点,再左节点,再右节点,就是前序遍历;如果先收集处理左节点,再中间节点,再右节点,就是中序遍历;如果先处理左节点,然后右节点,最后中间节点,就是后序遍历。
更容易理解的方式是:如果二叉树只有两层,比如这里只有1, 2, 3
三个节点,那么 1 -> 2 -> 3
就是前序遍历(优先处理1节点
),2 -> 1 -> 3
就是中序遍历(1节点
中间顺序被处理),2 -> 3 -> 1
就是后序遍历(1节点
最后被处理)。这里的前 中 后
就是1
在结果处理中的顺序。
在代码实现时,一般采用深度优先遍历 deep first search
(优先访问子节点)的方式。
/**1**/function binaryTree(root: TreeNode | null): number[] {
/**2**/ const res = []
/**3**/ function dsf(node: TreeNode | null) {
/**4**/ // 递归退出条件
/**5**/ if (node === null) {
/**6**/ return
/**7**/ }
/***********************8**********************/
/**9**/ // 如果左子节点存在,递归遍历左子树
/**10**/ node.left && dsf(node.left)
/**********************11**********************/
/**12**/ // 如果右子节点存在,递归遍历左子树
/**13**/ node.right && dsf(node.right)
/**********************14**********************/
/**15**/ }
/**16**/ dsf(root)
/**17**/}
通过递归的方式访问到了所有节点,在前中后序遍历下,只是处理结果的位置不同:
- 前序,优先收集中间节点。所以在判断当前节点不是
null
之后就可以收集,即第8
行的位置收集节点值 - 中序,
左->中->右
,先要遍历完左节点再收集,所以要在第11
行的位置收集节点值 - 后续,
左->右->中
,遍历左右节点之后再收集,所以要在第14
行的位置收集节点值
- 前序完整代码
function preorderTraversal(root: TreeNode | null): number[] {
const res: number[] = []
function dfs(node: TreeNode | null) {
if (node === null) return
res.push(node.val)
node.left && dfs(node.left)
node.right && dfs(node.right)
}
dfs(root)
return res
};
- 中序完整代码
function inorderTraversal(root: TreeNode | null): number[] {
const res = []
function dfs(node: TreeNode | null) {
if (node === null) return
node.left && dfs(node.left)
res.push(node.val)
node.right && dfs(node.right)
}
dfs(root)
return res
};
- 后序完整代码
function postorderTraversal(root: TreeNode | null): number[] {
const res = []
function dfs(node: TreeNode | null) {
if (node === null) return
node.left && dfs(node.left)
node.right && dfs(node.right)
res.push(node.val)
}
dfs(root)
return res
};