这次来了解一下二叉树
,以及相应的算法。以下代码并非所有都由本人所写,只是在此分享出来,以便大家学习。
有关javascript算法,数据结构的代码已上传至 javascript算法与数据结构。
主要内容:
/**
* 使用js实现一个二叉树。
* Tree 构造函数
* traverseDF 深度优先遍历
* traverseBF 广度优先遍历
* insert 插入
* inOrderTraverse中序遍历
* preOrderTraverse前序遍历
* postOderTraverse后序遍历
*/
声明一棵树:
function Tree () {
this._root;
}
声明一个节点:
function Node (data) {
this.data = data;
this.left = null;
this.right = null;
}
相关算法:
深度优先遍历
/**
* 深度优先遍历,先查看左孩子是否存在,若存在,传入recurse递归,
* 否则,再查看右孩子。若都不存在,对该节点执行callback操作。
*/
Tree.prototype.traverseDF = function (callback) {
(function recurse (currentNode) {
if (currentNode.left) {
recurse(currentNode.left);
}
if (currentNode.right) {
recurse(currentNode.right);
}
callback(currentNode);
})(this._root)
}
宽度优先遍历
/**
* 宽度优先遍历借助队列来实现。
*/
Tree.prototype.traverseBF = function (callback) {
var queue = new Queue();
if (!this._root) {
console.log('empty tree');
return;
}
queue.enqueue(this._root);
var currentNode = queue.dequeue();
while (currentNode) {
if (currentNode.left) {
queue.enqueue(currentNode.left);
}
if (currentNode.right) {
queue.enqueue(currentNode.right);
}
callback(currentNode);
currentNode = queue.dequeue();
}
}
插入树接节点:
/**
* 插入节点用到了宽度优先遍历的思想
*/
Tree.prototype.insert = function (data) {
var node = new Node(data);
var message = {
success: "Inserted successfully!",
}
if (!this._root) {
this._root = node;
return;
}
var queue = new Queue();
queue.enqueue(this._root);
var currentNode = queue.dequeue();
while (currentNode) {
if (currentNode.left) {
queue.enqueue(currentNode.left);
} else {
currentNode.left = node;
console.log(message.success);
return;
}
if (currentNode.right) {
queue.enqueue(currentNode.right);
} else {
currentNode.right = node;
console.log(message.success);
return;
}
currentNode = queue.dequeue();
}
}
中序遍历:
/**
* 中序遍历
*/
Tree.prototype.forInOrder = function (node) {
if (node) {
this.forInOrder(node.left);
console.log(node.data);
this.forInOrder(node.right);
}
}
Tree.prototype.inOrderTraverse = function () {
this.forInOrder(this._root);
}
中序遍历的非递归算法
/**
* 借助一个栈,先沿着左子树到叶节点,依次入栈,
* 再出栈遍历,对该栈顶节点的右子树进行统一的操作
*/
Tree.prototype.inOrder = function (callback) {
var currentNode = null;
if (this.root) {
currentNode = root;
} else {
return;
}
var stack = [];
do {
while (currentNode != null) {
stack.push(currentNode);
currentNode = currentNode.left;
}
if (!stack.length) {
stack.pop(currentNode);
callback(currentNode);
currentNode = currentNode.right;
}
} while (currentNode !== null && stack.length)
}
前序遍历
/**
* 前序遍历
*/
Tree.prototype.forPreOrder = function (node) {
if (node) {
console.log(node.data);
this.forPreOrder(node.left);
this.forPreOrder(node.right);
}
}
Tree.prototype.preOrderTraverse = function () {
this.forPreOrder(this._root);
}
当然还有前序遍历的非递归算法。
/**
* 算法关键思想是用栈为右子树预留位置。
* 可以利用数组作为一个栈。
*/
Tree.prototype.preOrder = function (callback) {
var currentNode = null;
if (this.root) {
currentNode = this.root;
} else {
return;
}
var stack = [];
while (currentNode) {
callback(currentNode);
if (currentNode.right) {
stack.push(currentNode.right);
}
if (currentNode.left) {
currentNode = currentNode.left;
} else {
currentNode = stack.pop();
}
}
}
后序遍历
/**
* 后序遍历
*/
Tree.prototype.forPostOrder = function (node) {
if (node) {
this.forPostOrder(node.left);
this.forPostOrder(node.right);
console.log(node.data);
}
}
Tree.prototype.postOderTraverse = function () {
this.forPostOrder(this._root);
}
最后给出队列的实现
function Queue () {
this._oldestIndex = 1;
this._newestIndex = 1;
this._storage = {};
}
Queue.prototype.enqueue = function (data) {
this._storage[this._newestIndex] = data;
this._newestIndex++;
}
Queue.prototype.dequeue = function () {
var oldestIndex = this._oldestIndex,
newestIndex = this._newestIndex,
deletedData;
if (oldestIndex !== newestIndex) {
deletedData = this._storage[oldestIndex];
delete this._storage[oldestIndex];
this._oldestIndex++;
return deletedData;
}
return null;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。