涉及的算法
- 创建二叉搜索树
- 插入节点
- 中序遍历、后序遍历
- DFS、BFS
- 最大值,最小值
- 寻找指定值 并返回路径
- 寻找二叉树是否有一条路径 其和为指定值
- 二叉树深度
- 之字形打印二叉树
- 层次打印二叉树
- 从根节点到叶子结点所有路径
**树的节点的定义**
class Node {
constructor(key){
this.key = key;
this.left = null;
this.right = null
};
}
class BinarySearchTree {
constructor() {
this.root = null;
}
**创建一个二叉搜索树**
create(arr){
for(let i = 0; i<arr.length;i++ ){
this.insert(arr[i])
}
console.log(this.storey)
}
**插入节点**
insert(key){
let node = new Node(key);
if (this.root === null){
this.root = node;
} else {
this._insert(this.root,node)
}
}
_insert(root,node) {
if (node.key <= root.key){
if (root.left === null){
root.left = node
} else {
this._insert(root.left,node)
}
}
else {
if (root.right === null){
root.right = node
} else {
this._insert(root.right,node);
}
}
}
**中序遍历**
inOrderTraverse(node,cb){
if (!node){
return null
}
if (node!==null){
this.inOrderTraverse(node.left,cb);
cb(node);
this.inOrderTraverse(node.right,cb);
}
}
**后续遍历**
houxvTraverse(node,cb){
if (!node){
return null
} else {
this.houxvTraverse(node.left,cb);
this.houxvTraverse(node.right,cb);
cb(node)
}
}
> *深度优先主要是利用栈,先压右子树,再压左子树
> 广度优先主要利用队列,先入左子树,再入右子树*
**深度优先非递归 利用栈 先进后出**
DFS(root,cb) {
let stack = [];
stack.push(root);
while (stack.length != 0) {
let node = stack.pop();
cb(node);
if (node.right) {
stack.push(node.right);
}
if (node.left) {
stack.push(node.left);
}
}
}
**广度优先非递归**
BFS(root,cb) {
let queue = [];
queue.push(root);
while (queue.length != 0) {
let node = queue.shift();
cb(node)
if (node.left) {
queue.push(node.left);
}
if (node.right) {
queue.push(node.right);
}
}
}
**最小值**
minNode(){
if (!this.root){
return null
}
let node = this.root;
while (node.left !== null){
node = node.left
}
return node.key
}
**最大值**
maxNode(){
let node = this.root
if (!node){
return null
}
while (node.right !==null){
node = node.right
}
return node.key
}
**寻找指定值 并返回路径**
search(value){
let arr = [];
let node = this.root;
return _search(node,value)
function _search(node,v) {
if (!node){
return false
}
arr.push(node.key)
if (v < node.key){
return _search(node.left,v)
}else if (v > node.key){
return _search(node.right,v)
} else if (v === node.key){
return arr
} else {
return false
}
}
}
**寻找二叉树是否有一条路径 其和为指定值**
pathSum(node,sum){
if (node === null){
return false
}
if (node.left===null&&node.right===null){
return sum===node.key?true:false
}
return this.pathSum(node.left,sum-node.key)||this.pathSum(node.right-node.key)
}
**二叉树深度**
deep(){
let deepnum = 0
return this._deep(this.root,deepnum)
}
_deep(node,deepnum){
if (node == null){
return 0
}
let left = this._deep(node.left),
right = this._deep(node.right);
return left>right? left+1:right+1
}
**之字型打印二叉树**
用栈存放奇数层数字 队列存放偶数层数字 ,读取每层的时候,将下一层的数据存入栈或者队列
printSnake(){
*1用来存奇数层 2用来存偶数层;偶数层从右子树开始存,同时存储的奇数层数字是从右边开始遍历,(同时奇数层得从左边开始遍历),符合先进后出,所以得用栈存放*
let stack1 = [],queue2 = [];
let level = 1,res = [];
stack1.push(this.root);
while (stack1.length!==0||queue2.length!==0){
if (level%2!==0){
**奇数层 从q1取值 并且把孩子节点存入queue2**
const node = stack1.pop();
res.push(node.key)
if (node.right){
queue2.push(node.right)
}
if (node.left){
queue2.push(node.left)
}
if (stack1.length ===0 ){
level++
}
}
else {
const node = queue2.shift();
res.push(node.key)
if (node.right){
stack1.push(node.right)
}
if (node.left){
stack1.push(node.left)
}
if (queue2.length ===0 ){
level++
}
}
}
console.log(res)
}
**二叉树层次打印**
printForLevel(){
let queue1 = [],queue2 = [];
let level = 1,res = [],allRes = [];
queue1.push(this.root);
while (queue1.length!==0||queue2.length!==0){
if (level%2!==0){
**奇数层 从q1取值 并且把孩子节点存入queue2**
const node = queue1.shift();
res.push(node.key)
if (node.left){
queue2.push(node.left)
}
if (node.right){
queue2.push(node.right)
}
if (queue1.length ===0 ){
level++
allRes.push(res);
res = [];
}
}
else {
const node = queue2.shift();
res.push(node.key)
if (node.left){
queue1.push(node.left)
}
if (node.right){
queue1.push(node.right)
}
if (queue2.length ===0 ){
level++
allRes.push(res);
res = [];
}
}
}
console.log(allRes)
}
**从根节点到叶子结点所有路径**
printAllPaths(node){
this.arr.push(node.key)
if (node.left===null&&node.right===null){
console.log(this.arr);
}else {
if (node.left){
this.printAllPaths(node.left)
}
if (node.right) {
this.printAllPaths(node.right)
}
}
this.arr.pop()
}
}