解题思路一:递归
1.递归调用,不断把子孙左节点传入,直到最后一层再无左节点的值
2.打印当前节点值
2.判断有无右节点,如果有的话重复步骤【1】【2】
【1】向函数传入{2,1,3} 这个左子树,发现还有左节点{1}再调用
【2】左节点{1}没有子左节点了,退出函数,
【3】打印{1}
【4】节点{1}没有右子树了,退出函数,代表我们当前左子树遍历完成
【5】打印当前节点{2}
【5】传入右子树遍历,重复步骤
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthSmallest = function(root, k) {
if(!root) return
let stack = [], res = []
// 1.采用递归
function eachTree(ntree) {
if (!ntree) {return}
eachTree(ntree.left) // 每次传入左子树,等把值访问完了,退出当前循环,执行循环的下一句
res.push(ntree.val)
eachTree(ntree.right)
}
eachTree(root)
}
解题思路二:迭代
1.新建一个调用栈,用来存放每次要访问的子树
2.新建一个指针,用来存放每次要访问的节点
3.循环左子树,不停将指针指向当前节点的左子树,然后推入调用栈
4.弹出栈顶元素(最小子树),写入当前节点值
5.循环右子树
【1】从枝到叶不断写入左子树节点到栈中,依次是根元素A{4,2,6,1,3,5,7},它的左子树B{2,1,3},B的左节点{1}
【2】弹出栈顶元素,打印{1}
【3】弹出{2,1,3}打印{2}
【4】{2,1,3}存在右子节点为{3},打印{3}
【5】弹出 {4,2,6,1,3,5,7},打印当前节点{4}
【6】对右子树重复以上步骤
代码
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @param {number} k
* @return {number}
*/
var kthSmallest = function(root, k) {
if(!root) return
let stack = [], res = []
// 2.采用迭代
let p = root
while(stack.length || p) {
while(p) { // 不断将左子树写入栈中,栈顶元素即最小左子树
stack.push(p)
p = p.left
}
const n = stack.pop() // 弹出并访问
res.push(n.val)
p = n.right // 判断有无右节点
}
console.log('res', res)
return res[k-1]
// }
}