春招来了,辞了职在家里准备再找份实习工做。相信你们,尤为是大3、大四的同窗都常常在招聘要求上看到这样一条要求:熟悉常见的数据结构与算法。常见的数据结构一般有:链表、二叉树,若是要求再高点,可能会让你实现红黑树、AVL树这种高级的数据结构。因而可知,数据结构与算法仍是比较重要的,最近也是在复习这方面的知识。本篇为复习过程当中遇到过的总结,同时也给各位跟我同样准备面试的同窗一份参考。另外,因为篇幅有限,本篇的重点在于二叉树的常见算法以及实现。javascript
以前写过相关的文章,是关于如何建立及遍历二叉树的,这里再也不赘述。提供连接给各位感兴趣的小伙伴,点此跳转前端
对于一棵二叉树,翻转它的左右子树,以下图所示:java
其实这样咱们仍是不知道二叉树是如何翻转的,咱们能够用第一张图的二叉树为例子,看一下翻转的具体过程。面试
根据上面的推理过程咱们能够得出以下的代码:算法
function reverseTree(root){
if( root !== null){
[root.left, root.right] = [root.right, root.left]
reverseTree(root.left)
reverseTree(root.right)
}
}
复制代码
虽然推理过程比较复杂(也多是写的比较啰嗦。。),可是仔细观察代码,这和遍历的代码彷佛也没多大差异,只是把输出结点变为了交换结点。微信
一棵左右彻底对称的二叉树是这样的: 数据结构
按照咱们正常的思惟,看对称与否,首先看左边,而后看右边,最后比较左右是否相等。同时咱们注意到,在二叉树深度比较大的时候,咱们光是比较左右是不够的。能够观察到,咱们比较完左右之后还须要比较左的左和右的右,比较左的右和右的左post
这么看是比较绕,接下来咱们来看图分析:spa
function isSymmetrical(pRoot) {
// write code here
if(!pRoot){
return true
}
return funC(pRoot.left, pRoot.right)
}
function funC(left, right){
if(!left){
return right === null
}
if(!right){
return false
}
if(left.val !== right.val){
return false
}
return funC(left.right, right.left) && funC(left.left, right.right)
}
复制代码
function deep(root){
if(!root){
return 0
}
let left = deep(root.left)
let right = deep(root.right)
return left > right ? left + 1 : right + 1
}
复制代码
二叉树的宽度是啥?我把它理解为具备最多结点数的层中包含的结点数,好比下图所示的二叉树,其实它的宽度就是为4: 3d
根据上图,咱们如何算出二叉树的宽度呢?其实有个很简单的思路:
根据分析过程,咱们能够利用队列这种数据结构来实现这个算法,代码以下:
function width(root){
if(!root){
return 0
}
let queue = [root], max = 1, deep = 1
while(queue.length){
while(deep--){
let temp = queue.shift()
if(temp.left){
queue.push(temp.left)
}
if(temp.right){
queue.push(temp.right)
}
}
deep = queue.length
max = max > deep ? max : deep
}
return max
}
复制代码
前序遍历: 前序遍历首先访问根结点而后遍历左子树,最后遍历右子树。
中序遍历: 中序遍历首先访问左子树而后遍历根节点,最后遍历右子树。
后序遍历: 后序遍历首先遍历左子树,而后遍历右子树,最后访问根结点
根据前序遍历产生的序列和中序遍历产生的序列生成一颗二叉树
假若有这么一棵二叉树:
function reConstructBinaryTree(pre, vin) {
if(!pre || !vin || !pre.length || !vin.length){
return null
}
let root = new TreeNode(pre[0]),
tIndex = vin.indexOf(pre[0]),
leftIn = [],leftPre = [],rightIn = [],rightPre = []
for(let i = 0; i < tIndex; i++){
leftIn.push(vin[i])
leftPre.push(pre[i+1])
}
for(let i = tIndex+1; i < pre.length; i++){
rightIn.push(vin[i])
rightPre.push(pre[i])
}
//递归
root.left = reConstructBinaryTree(leftPre, leftIn)
root.right = reConstructBinaryTree(rightPre, rightIn)
return root
}
复制代码
以上思路、代码有错漏请在评论区指出!
代码部分来自牛客网--剑指offer,相应的题目也均可以在上面找到。不过在这期间,我也是找到了份实习工做,年后就要去搬砖了。既然找到了,春招就不参与了(春招难度比秋招难太多了)但愿看这篇文章的同窗们也能找到份合适的工做。
扫描下方的二维码或搜索「tony老师的前端补习班」关注个人微信公众号,那么就能够第一时间收到个人最新文章。