给定一棵二叉树的前序遍历和中序遍历,求其层序遍历的结果。
输入:
两个字符串,其长度n均小于等于26
第一行为前序遍历,第二行为中序遍历
二叉树中的结点名称以大写字母表示:A,B,C….最多26个结点
输出:
输入样例可能有多组,对于每组测试样例
输出一行,为层序遍历的字符串
样例输入:
FDXEAG
XDEFAG
样例输出:
XEDGAF
1、先序遍历的第一个节点就是整棵二叉树的根节点,因此根据二叉树的根节点找到根节点在中序遍历中的位置。
2、中序遍历中的根节点的左边就是左子树,右边就是右子树,因此可以通过不断递归,来找到每一棵树。
3、得到二叉树后,通过层序遍历将结果添加到结果的子串当中。
4、层序遍历需要一个队列来记录遍历顺序。
// 获取输入
const input1 = "FDXEAG"
const input2 = "XDEFAG"
// 将字符串拆分为数组
const preOrder = input1.split("")
const inOrder = input2.split("")
//创建二叉树
function createNode(preOrder,inOrder) {
// 先序遍历长度为0,说明整个树已经遍历完成
if(preOrder.length == 0) return null
// 中序遍历长度为0,说明该节点的上一个节点已经是叶子节点
if(inOrder.length == 0) return null
// 先序遍历的第一个节点是整个二叉树的根节点
const val = preOrder.shift()
// 找到根节点在中序遍历中所在的位置
const index = inOrder.indexOf(val)
// 中序遍历的左边就是左子树,右边就是右子树
const left = inOrder.slice(0,index)
const right = inOrder.slice(index+1)
// 创建二叉树的各个节点
function Node() {
// 根节点
this.val = val
// 左节点
this.left = createNode(preOrder,left)
// 右节点
this.right = createNode(preOrder,right)
}
const node = new Node()
return node
}
//广度优先搜索,也即层序遍历
function BFS(arr,str) {
// 根节点
const node = arr.shift()
if(node) {
// 如果节点存在就将节点值加入到字符串结果当中
str += node.val
// 如果存在左子节点,就将左子节点加入到arr数组
if(node.left) {
arr.push(node.left)
}
// 如果存在右子节点,就将右子节点加入到arr数组
if(node.right) {
arr.push(node.right)
}
// 递归,直到节点为空时返回str层序遍历的结果
str = BFS(arr,str)
}
return str
}
// 生成二叉树,得到根节点
const tree = createNode(preOrder, inOrder)
// 根据添加到arr数组中的先后顺序不同,也就是通过队列来记录遍历顺序
const temp = [tree]
let bfs = BFS(temp, '')
// 输出结果
console.log(bfs); //打印结果:FDAXEG
// 后序遍历(左右根)
function LRD(node,arr) {
if(node.left) {
LRD(node.left,arr)
}
if(node.right) {
LRD(node.right,arr)
}
arr.push(node.val)
}
const tree = createNode(preOrder, inOrder)
const lrd = []
LRD(tree,lrd)
console.log('后序遍历结果是:'+lrd.join(''))
//打印结果:
//后序遍历结果是:XEDGAF
//深度优先遍历(前序遍历 根左右)
function DFS(node,str) {
str += node.val
if(node.left) {
str = DFS(node.left,str)
}
if(node.right) {
str = DFS(node.right,str)
}
return str
}
// 生成二叉树,得到根节点
const tree = createNode(preOrder, inOrder)
let dfs = DFS(tree,'')
console.log('深度优先遍历结果是:'+dfs)
//打印结果是:
//深度优先遍历结果是:FDXEAG
// 获取输入
const input1 = "FDXEAG"
const input2 = "XDEFAG"
// 将字符串拆分为数组
const preOrder = input1.split("")
const inOrder = input2.split("")
//创建二叉树
function createNode(preOrder,inOrder) {
// 先序遍历长度为0,说明整个树已经遍历完成
if(preOrder.length == 0) return null
// 中序遍历长度为0,说明该节点的上一个节点已经是叶子节点
if(inOrder.length == 0) return null
// 先序遍历的第一个节点是整个二叉树的根节点
const val = preOrder.shift()
// 找到根节点在中序遍历中所在的位置
const index = inOrder.indexOf(val)
// 中序遍历的左边就是左子树,右边就是右子树
const left = inOrder.slice(0,index)
const right = inOrder.slice(index+1)
// 创建二叉树的各个节点
function Node() {
// 根节点
this.val = val
// 左节点
this.left = createNode(preOrder,left)
// 右节点
this.right = createNode(preOrder,right)
}
const node = new Node()
return node
}
//广度优先搜索,也即层序遍历
function BFS(arr,str) {
// 根节点
const node = arr.shift()
if(node) {
// 如果节点存在就将节点值加入到字符串结果当中
str += node.val
// 如果存在左子节点,就将左子节点加入到arr数组
if(node.left) {
arr.push(node.left)
}
// 如果存在右子节点,就将右子节点加入到arr数组
if(node.right) {
arr.push(node.right)
}
// 递归,直到节点为空时返回str层序遍历的结果
str = BFS(arr,str)
}
return str
}
//深度优先搜索,也即前序遍历
function DFS(node,str) {
str += node.val
if(node.left) {
str = DFS(node.left,str)
}
if(node.right) {
str = DFS(node.right,str)
}
return str
}
// 后序遍历
function LRD(node,arr) {
if(node.left) {
LRD(node.left,arr)
}
if(node.right) {
LRD(node.right,arr)
}
arr.push(node.val)
}
// 生成二叉树,得到根节点
const tree = createNode(preOrder, inOrder)
// 根据添加到arr数组中的先后顺序不同,也就是通过队列来记录遍历顺序
const temp = [tree]
let bfs = BFS(temp, '')
let dfs = DFS(tree,'')
const lrd = []
LRD(tree,lrd)
console.log('后序遍历结果是:'+lrd.join(''))
console.log('层序遍历结果是:'+bfs)
console.log('深度优先遍历结果是:'+dfs)
本文参考了该博主的优质文章:华为机试练习(二)二叉树遍历_下一个路口遇见你48的博客-CSDN博客_华为机试二叉树