为什么使用二叉树
二叉树的前序遍历可以用来显示目录结构等;中序遍历可以实现表达式树,在编译器 底层很有用;后序遍历可以用来实现计算目录内的文件及其信息等。
二叉树的遍历
二叉树有深度遍历和广度遍历, 深度遍历有前序、 中序和后序三种遍历方法。 广度遍历就是层次遍历
四种遍历的主要思想:
前序遍历:访问根–>遍历左子树–>遍历右子树; 中序遍历:遍历左子树–>访问根–>遍历右子树; 后序遍历:遍历左子树–>遍历右子树–>访问根; 广度遍历:按照层次一层层遍历;
1、先序遍历
递归遍历
var list = []; //定义保存先序遍历结果的数组
function preOrderTraversal(node) {
if (node) { // 判断是否为空
list.push(node.value);
preOrderTraversal(node.left);
preOrderTraversal(node.right);
}
}
非递归遍历
function preOrderTraversal(node) {
var list = []; //定义保存先序遍历结果的数组
if (node) { // 判断是否为空
let stack = [node]; // 将二叉树压入栈
while(stack.length !== 0) {
node = stack.pop();
list.push(node.value);
if (node.right)
stack.push(node.right); // 压入右子树
if (node.left)
stack.push(node.left); // 压入左子树
}
}
}
先序非递归遍历是利用了栈,将根结点放入栈中,然后再取出来,将值放入结果数
组,然后如果存在右子树,将右子树压入栈,如果存在左子树,将左子树压入栈,然后
循环判断栈是否为空,重复上述步骤。
2、中序遍历
递归遍历
var list = []; //定义保存中序遍历结果的数组
function inOrderTraversal(node) {
if (node) { // 判断是否为空
inOrderTraversal(node.left);
list.push(node.value);
inOrderTraversal(node.right);
}
}
非递归遍历
function inOrderTraversal(node) {
var list = []; //定义保存中序遍历结果的数组
if (node) { //判断二叉树是否为空
var stack = []; //建立一个栈
while (stack.length !== 0 || node) {
//如果栈不为空或结点不为空,则循环遍历
if (node) { //如果结点不为空
stack.push(node); //将结点压入栈
node = node.left; //将左子树作为当前结点
} else { //左子树为空,即没有左子树的情况
node = stack.pop(); //将结点取出来
list.push(node.value); //将取出结点的值存入数组中
node = node.right; //将右结点作为当前结点
}
}
}
}
3、后序遍历
var list = []; //定义保存中序遍历结果的数组
function postOrderTraversal(node) {
if (node) { // 判断是否为空
postOrderTraversal(node.left);
postOrderTraversal(node.right);
list.push(node.value);
}
}
4、广度遍历
function breadthTraversal(node) {
let list = [];
if (node) {
let queue = [node]; // 将二叉树放入队列
while(queue.length !== 0) {
node = queue.shift();
list.push(node);
if (node.left) queue.push(node.left); // 将左子树存入队列
if (node.right) queue.push(node.right);// 将右子树存入队列
}
}
}