本文思路如下:
- 二叉搜索树的概念
- 该题解题思路
- 二叉树前序遍历的迭代和递归法
- 二叉树中序遍历的迭代和递归法
- 二叉树后序遍历的迭代和递归法
二叉搜索树
概念:二叉搜索树又叫做二叉排序树,他的左子树上的节点值都比根节点小,他的右子树上的节点值都比根节点大。同时,他的左右子树都分别是二叉搜索树。因此通过中序遍历可以轻松得到一个升序序列。
解题思路
该题直接用中序遍历遍历二叉树(用迭代法和递归法都可以),得到升序序列,然后访问第k大节点即可。 代码如下:
var kthLargest = function(root, k) {
//二叉树的中序遍历
//1.递归法(回溯) 2.迭代法(通过栈来实现)
//递归法
let res=[]
function back(node){
if(!node){ return }
back(node.left)
res.push(node.val)
back(node.right)
}
back(root)
return res[res.length-k]
};
二叉树遍历之递归法(回溯)
前序遍历
function SHU(root){
//二叉树前序遍历的递归法
let res=[]
function back(node){
if(!node){
return
}
res.push(node.val)
back(node.left)
back(node.right)
}
back(root)
}
中序遍历
function SHU(root){
//二叉树前序遍历的递归法
let res=[]
function back(node){
if(!node){
return
}
back(node.left)
res.push(node.val)
back(node.right)
}
back(root)
}
后序遍历
function SHU(root){
//二叉树前序遍历的递归法
let res=[]
function back(node){
if(!node){
return
}
back(node.left)
back(node.right)
res.push(node.val)
}
back(root)
}
总结
可以看出二叉树递归的三种遍历几乎没有区别,只是添加值(res.push(node.val))的位置不同。
二叉树遍历之迭代法(辅助栈)
前序遍历
两个变量,一个辅助栈stack,一个输出数组res。先将根节点压入satck栈底,然后再进入循环while(stack.length),一遍遍的将栈顶元素取出,然后右节点入栈,左节点入栈。
function SHU(root){
let stack=[root]
let res=[]
while(stack.length){
//栈顶出栈
let node=stack.pop()
res.push(node.val)
node.right&&stack.push(node.right)
node.left&&stack.push(node.left)
}
}
后序遍历
后序遍历是左右根,而前序遍历是根左右,将前序遍历反过来就是右左根。所以只需要在前序遍历上面进行一点点改动,就可以得到中序遍历。 两个变量,一个辅助栈stack,一个输出数组res。先将根节点压入satck栈底,然后再进入循环while(stack.length),一遍遍的将栈顶元素取出,然后左节点入栈,右节点入栈。
function SHU(root){
let stack=[root]
let res=[]
while(stack.length){
//栈顶出栈
let node=stack.pop()
//-------------------------改动一(将根右左颠倒便是左右根)
res.unshift(node.val)
//-------------------------改动二(和前序遍历相比交换顺序 根左右---》根右左)
node.left&&stack.push(node.left)
node.right&&stack.push(node.right)
}
}
中序遍历(最难理解的一部分)
三个变量,一个stack辅助栈,一个输出数组res,一个cur暂存节点(指针)。
while(栈非空||指针(cur)非空)
1.所有的左子树入栈,包括根节点
2.出栈访问
3.指针指向右节点
function SHU(root){
let stack=[]
let res=[]
let cur=root
while(stack.length||cur){
//所有左子树进栈
while(cur){
stack.push(cur)
cur=cur.left
}
let node=stack.pop()
res.push(node.val)
if(node.right){
cur=node.right
}
}
}
总结
文章详细说明了二叉树遍历的六种方法(迭代(辅助栈)和递归(回溯)),其中递归很简单。前后序遍历的迭代法只有两处改动。中序遍历的迭代法是最难理解的,但是记住步骤也不难(1.所有左子树入栈包括根节点,2.出栈访问 3.指针指向右节点)。迭代法中前后序遍历的while条件都是stack.length,而中序遍历的while条件是(stack.length||cur)