节点结构
使用js
function TreeNode(val,left,right)
{
this.val=(val===undefined)?0:val;
this.left=(left===undefined)?null:left;
this.right=(right ====undefined)?null:right;
}
遍历方式
深度优先搜索 (递归+迭代)
主要采用递归实现 , 栈是递归的一种实现结构
递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。
递归函数三要素
- 确定递归函数参数以及返回值
- 确定递归的终止条件
- 确定单层逻辑
前序
// 前序遍历
var preorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
// 终止条件
if(!root) return;
// 单层逻辑
res.push(root.val);//中
dfs(root.left);//左
dfs(root.right);//右
}
dfs(root);
return res;
}
//前序遍历
var preorderTraversal = function(root) {
let res = [];
let stack = []; // 模拟栈 先进后出
if(root) stack.push(root);
while(stack.length){
let node = stack.pop();
res.push(node.val);
if(node.right) stack.push(node.right); //注意先右后左
if(node.left) stack.push(node.left);
}
return res;
}
中序
var inorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
// 终止条件
if(!root) return;
// 单层逻辑
dfs(root.left);//左
res.push(root.val);//中
dfs(root.right);//右
}
dfs(root);
return res;
}
var inorderTraversal = function(root) {
let res = [];
let stack = [];
let cur = root;
while(cur || stack.length){
while(cur){
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
res.push(cur.val); //左出栈 中出栈
cur = cur.right; //右出栈
}
return res;
}
后序
var postorderTraversal = function(root) {
let res = [];
const dfs = (root) => {
// 终止条件
if(!root) return;
// 单层逻辑
dfs(root.left);//左
dfs(root.right);//右
res.push(root.val);//中
}
dfs(root);
return res;
}
var postorderTraversal = function(root) {
let res = [];
let stack = [root];
let cur = root;
while(cur || stack.length){
// 中
let cur= stack.pop();
res.push(cur.val);
// 先左后右
if(cur.left) stack.push(cur.left);
if(cur.right) stack.push(cur.right);
}
return res.reverse();
}
广度优先搜索
主要采用队列模拟实现
层序
从左到右一层层去遍历二叉树
需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。
var levelOrder = function(root) {
let res = [], queue = [];
queue.push(root);
if(root === null) {
return res;
}
while(queue.length !== 0) {
// 记录当前层级节点数
let length = queue.length;
//存放每一层的节点
let curLevel = [];
for(let i = 0;i < length; i++) {
// 从队头取出一个节点
let node = queue.shift();
curLevel.push(node.val);
// 存放当前层下一层的节点
node.left && queue.push(node.left);
node.right && queue.push(node.right);
}
//把每一层的结果放到结果数组
res.push(curLevel);
}
return res;
}