二叉树前序中序后序javascript_javascript生成二叉树,前中后序遍历

**二叉树是一种数据结构。其特点是:

1.由一系列节点组成,具有层级结构。每个节点的特性包含有节点值、关系指针。节点之间存在对应关系。

2.树中存在一个没有父节点的节点,叫做根节点。树的末尾存在一系列没有子节点的节点,称为叶子节点。其他可以叫做中间节点。

3.树的根节点位于第一层,层级数越大,节点位置越深,层级数也叫做树高。

**排序二叉树为二叉树的一种类型,其特点是:

1.节点分为左右子树。

2.在不为空的情况下,左子树子节点的值都小于父节点的值。

3.在不为空的情况下,右子树子节点的值都大于父节点的值。

4.每个节点的左右子树都按照上述规则排序。

(一)生成二叉树

// 将值生成节点,节点包括:节点值、左指针、右指针

class Node {

constructor(key) {

this.key = key;

this.left = null;

this.right = null;

}

}

// 二叉树

class BinaryTree {

constructor() {

this.root = null; // 根节点

}

// 插入,插入的是一个节点,所以应该先把值生成节点(包括节点值,左指针,右指针)

insert(key) {

const newNode = new Node(key);

// 如果根节点为空,则新节点作为根节点,否则在根节点下进行插入

if (this.root === null) {

this.root = newNode;

}

this.insertNode(this.root, newNode);

}

// 有根节点的情况下插入值

insertNode(root, newNode) {

if (newNode.key < root.key) {

// 进入左子树

if (root.left === null) {

// 左子树为空

root.left = newNode;

} else {

// 左子树已存在

this.insertNode(root.left, newNode);

}

} else if (newNode.key > root.key) {

// 进入右子树

if (root.right === null) {

// 右子树为空

root.right = newNode;

} else {

// 右子树已存在

this.insertNode(root.right, newNode);

}

}

}

}

const binaryTree = new BinaryTree();

var keys = [19, 8, 15, 24, 45, 12, 5];

keys.forEach((key) => binaryTree.insert(key));

console.log(binaryTree);

(二)二叉树的遍历

1. 中序遍历

(1)递归方法

// 中序遍历:递归方法

var inorderTraversal = function (root) {

var result = [];

pushRoot(root, result);

return result;

};

function pushRoot(root, result) {

if (root !== null) {

// 左

if (root.left !== null) {

pushRoot(root.left, result);

}

// 中

result.push(root.key);

// 右

if (root.right !== null) {

pushRoot(root.right, result);

}

}

}

// 注意这里传入的是binaryTree.root,而不是binaryTree

inorderTraversal(binaryTree.root); // [5, 8, 12, 15, 19, 24, 45]

(2)非递归方法(栈)

var inorderTraversal = function (root) {

let result = [];

let stack = [];

let node = root;

while (node !== null || stack.length !== 0) {

if (node !== null) {

stack.push(node);

node = node.left; // 遍历左,存入栈中

} else {

debugger;

// node===null时说明左边没有了,那么栈顶就是最左边的(最小的)

node = stack.pop();

result.push(node.key);

node = node.right; //看右边有没有

}

}

console.log(result); // [5, 8, 12, 15, 19, 24, 45]

return result;

};

inorderTraversal(binaryTree.root);

2.前序遍历

(1)递归方法

// 前序遍历 递归

var preOrderTraversal = function (root) {

var res = [];

preOrder(root, res);

return res;

};

function preOrder(root, res) {

if (root !== null) {

// 中

res.push(root.key);

// 左

preOrder(root.left, res);

// 右

preOrder(root.right, res);

}

}

console.log(preOrderTraversal(binaryTree.root)); // [19, 8, 5, 15, 12, 24, 45]

(2)非递归方法(栈)

var preOrderTraversal = function (root) {

var res = [];

var stack = [];

var node = root;

while (node !== null || stack.length !== 0) {

if (node !== null) {

res.push(node.key);

stack.push(node);

node = node.left;

} else {

node = stack.pop();

node = node.right;

}

}

return res

};

console.log(preOrderTraversal(binaryTree.root)) // [19, 8, 5, 15, 12, 24, 45]

3.后序遍历

(1)递归方法

var afterOrderTraversal = function (root) {

var res = [];

afterOrder(root, res);

return res;

};

function afterOrder(root, res) {

if (root !== null) {

// 左

afterOrder(root.left, res);

// 右

afterOrder(root.right, res);

// 中

res.push(root.key);

}

}

console.log(afterOrderTraversal(binaryTree.root)); // [5, 12, 15, 8, 45, 24, 19]

(2)非递归方法

首先要搞清楚先序、中序、后序的非递归算法共同之处:用栈来保存先前走过的路径,以便可以在访问完子树后,可以利用栈中的信息,回退到当前节点的双亲节点,进行下一步操作。

后序遍历的非递归算法是三种顺序中最复杂的,原因在于,后序遍历是先访问左、右子树,再访问根节点,而在非递归算法中,利用栈回退到时,并不知道是从左子树回退到根节点,还是从右子树回退到根节点,如果从左子树回退到根节点,此时就应该去访问右子树,而如果从右子树回退到根节点,此时就应该访问根节点。所以相比前序和后序,必须得在压栈时添加信息,以便在退栈时可以知道是从左子树返回,还是从右子树返回进而决定下一步的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值