递归与迭代的区别
-
递归(recursion):递归常被用来描述以自相似方法重复事物的过程,在数学和计算机科学中,指的是在函数定义中使用函数自身的方法。(A调用A)
-
迭代(iteration):重复反馈过程的活动,每一次迭代的结果会作为下一次迭代的初始值。(A重复调用B)
算法题
理论上递归都可以用迭代实现
- 遍历二叉树递归范式
function recursion(root) {
if(!root) return
// ...前序遍历在这里处理当前值root.val
recursion(root.left) // 处理左边
// ...中序遍历在这里处理当前值root.val
recursion(root.right) // 处理右边
// ...后序遍历在这里处理当前值root.val
}
- 层序遍历二叉树迭代范式
var queue = [root] // 用双端队列处理
while (queue.length) {
var len = queue.length
while (len--) {
var top = queue.shift() // 取出当前需要处理的值
// ...这里处理当前值top.val
// 处理左右插入队列尾部,进入下一轮循环
top.left && queue.push(top.left)
top.right && queue.push(top.right)
}
}
102. 二叉树的层序遍历
- 递归
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function (root) {
var ans = []
function recursion(root, k) {
if(!root) return
if(!ans[k]) ans.push([])
ans[k].push(root.val)
recursion(root.left, k + 1)
recursion(root.right, k + 1)
}
recursion(root, 0, ans)
return ans
};
- 迭代
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function (root) {
var ans = []
if(!root) return ans
var queue = [root]
while (queue.length) {
var len = queue.length
var tmp = []
while (len--) {
var top = queue.shift()
tmp.push(top.val)
top.left && queue.push(top.left)
top.right && queue.push(top.right)
}
ans.push(tmp)
}
return ans
};
107. 二叉树的层序遍历 II
- 递归
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrderBottom = function (root) {
var ans = []
function recrusion(root, k) {
if(!root) return
if(!ans[ans.length - 1 - k]) ans.unshift([])
ans[ans.length - 1 - k].push(root.val)
recrusion(root.left, k + 1)
recrusion(root.right, k + 1)
}
recrusion(root, 0)
return ans
};
- 迭代
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrderBottom = function (root) {
var ans = []
if (!root) return ans
var queue = [root]
while (queue.length) {
var len = queue.length
var tmp = []
while (len--) {
var top = queue.shift()
tmp.push(top.val)
top.left && queue.push(top.left)
top.right && queue.push(top.right)
}
ans.unshift(tmp)
}
return ans
};
103. 二叉树的锯齿形层序遍历
- 递归
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var zigzagLevelOrder = function(root) {
var ans = []
function recursion(root, k) {
if(!root) return
if(!ans[k]) ans.push([])
if(k % 2 === 0) ans[k].push(root.val)
else ans[k].unshift(root.val)
recursion(root.left, k + 1)
recursion(root.right, k + 1)
}
recursion(root, 0)
return ans
};
- 迭代
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var zigzagLevelOrder = function(root) {
var ans = []
if(!root) return ans
var queue = [root]
var flag = true
while(queue.length) {
var len = queue.length
var tmp = []
while(len--){
var top = queue.shift()
if(flag) tmp.push(top.val)
else tmp.unshift(top.val)
top.left && queue.push(top.left)
top.right && queue.push(top.right)
}
ans.push(tmp)
flag = !flag
}
return ans
};
589. N 叉树的前序遍历
- 递归
/**
* @param {Node|null} root
* @return {number[]}
*/
var preorder = function (root) {
var ans = []
function recursion(root) {
if(!root) return
ans.push(root.val)
for(var i = 0; i < root.children.length; i++){
recursion(root.children[i])
}
}
recursion(root)
return ans
};
- 迭代
/**
* @param {Node|null} root
* @return {number[]}
*/
var preorder = function (root) {
var ans = []
if (!root) return ans
var queue = [root]
while (queue.length) {
var top = queue.shift()
ans.push(top.val)
var children = top.children
// 关键步骤,children反向添加到队列前
for (var i = children.length - 1; i >= 0; i--) {
queue.unshift(children[i])
}
}
return ans
};