【JavaScript】前端算法题(重建二叉树、反向输出链表每个节点)

cnblogs 2024-07-30 08:11:00 阅读 56

今天复习了一些前端算法题,写到一两道比较有意思的题:重建二叉树、反向输出链表每个节点

前言

今天复习了一些前端算法题,写到一两道比较有意思的题:重建二叉树、反向输出链表每个节点

题目

重建二叉树: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列 {1,2,4,7,3,5,6,8} 和中序遍历序列 {4,7,2,1,5,3,8,6},则重建二叉树并返回。

思路

前序遍历(根左右)和中序遍历(左根右)

思路就是使用递归把他分化为每个小的二叉树,然后都根据前序遍历(根左右)和中序遍历(左根右)的特性,前序的首元素就是根,然后再找到中序的根,根的左边就是左右边就是右,再进行递归,直到前序为null的时候就代表没有根节点了,那这个元素就是尾节点

一.

①[1,2,4,7,3,5,6,8],[4,7,2,1,5,3,8,6]-> val=>1 ->L([2,4,7],[4,7,2]) & R([3,5,6,8],[5,3,8,6]) 根节点 1 ,有左右节点

二.

①L([2,4,7],[4,7,2])-> val=>2 ->L([4,7],[4,7]) && R(null , null) 根节点2(属1的左节点) ,有左节点,无右节点

②R([3,5,6,8],[5,3,8,6])-> val=>3 ->L([5],[5]) && R([6,8],[6,8]) 根节点3(属1的右节点) ,有左右节点

三.

①L([4,7],[4,7]) ->val=>4 -> L(null , null) && R([7],[7]) 根节点4(属2的左节点) ,有右节点,无左节点

②R([6,8],[8,6]) -> val=>6 -> L([8] , [8]) && R(null , null) 根节点6(属3的右节点),有左节点,无右节点

③L([5],[5]) -> val=>5->(null,null)->终止 尾节点5(属3的左节点)

四.

①R([7],[7]) -> val=>7 ->终止 尾节点7(属4的右节点)

②L([8],[8]) -> val=>8 ->终止 尾节点8(属6的左节点)

代码实现

<code>function rebuildBinaryTree(front, centre) {

//判断是否为空节点

if (!front || front.length == 0) {

return null;

}

// 根节点

var TreeNode = {

val: front[0]

};

for (var i = 0; i < front.length; i++) {

//找到中序遍历根节点位置

if (centre[i] === front[0]) {

//中序遍历(左根右)

//根节点左边的节点为该节点的左边

TreeNode.left = rebuildBinaryTree(front.slice(1, i + 1), centre.slice(0, i));

//根节点右边的节点为该节点的右边

TreeNode.right = rebuildBinaryTree(front.slice(i + 1), centre.slice(i + 1));

}

}

return TreeNode;

}

let tree = rebuildBinaryTree([1, 2, 4, 7, 3, 5, 6, 8], [4, 7, 2, 1, 5, 3, 8, 6])

console.log(tree)

题目

从尾到头打印链表: 输入一个链表,从尾到头打印链表每个节点的值。

思路

由于链表是单向的,我们不能直接从头节点开始反向遍历。

所以可以使用数组来模拟栈。迭代遍历链表,将链表每个节点压入栈中,然后再依次从栈中弹出并打印。

代码实现

// 定义一个节点类,结构data表示节点数据、next表示下个节点的指针

class Node {

constructor(data) {

this.data = data

this.next = null

}

}

function printNode(node) {

// 定义一个数组表示模拟栈

let stack = new Array()

// 初始化当前节点为传入的节点

let NodeNextElm = node

//判断下个节点指针是否为空

while (NodeNextElm !== null) {

//压栈

stack.push(NodeNextElm.data)

//存储下个节点的指针

NodeNextElm = NodeNextElm.next

}

while (stock.length > 0) {

//当栈不为空时,循环弹出栈顶元素并打印

console.log(stack.pop())

}

}

//初始化链表

//新建链表节点

const node1 = new Node(1)

const node2 = new Node(2)

const node3 = new Node(3)

//手动存储下个节点的指针

node1.next = node2

node2.next = node3

//调用

printNode(node1)

过程解析

一. 进入,此时的NodeNextElm:{

"data": 1,

"next": {

"data": 2,

"next": {

"data": 3,

"next": null

}

}

}

此时进入while循环:

①第一次循环:

栈stack:[1]

NodeNextElm:{

"data": 2,

"next": {

"data": 3,

"next": null

}

}

②第二次循环:

栈stack:[1,2]

NodeNextElm:{

"data": 3,

"next": null

}

③第三次循环:

栈stack:[1,2,3]

NodeNextElm:null

循环结束

pop()弹出栈并打印:3,2,1

上述为个人整理内容,水平有限,如有错误之处,望各位园友不吝赐教!如果觉得不错,请点个赞和关注支持一下!谢谢~๑•́₃•̀๑ [鲜花][鲜花][鲜花]



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。