华为机考:二叉树的层序遍历

题目:

给定一棵二叉树的前序遍历和中序遍历,求其层序遍历的结果。

输入:
两个字符串,其长度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博客_华为机试二叉树

你可能感兴趣的:(牛客,算法,算法,广度优先,javascript,数据结构)