首頁 >web前端 >js教程 >javascript實作二元樹的程式碼介紹

javascript實作二元樹的程式碼介紹

不言
不言原創
2018-08-22 11:17:041531瀏覽

這篇文章帶給大家的內容是關於javascript實作二元樹的程式碼介紹,有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

樹是資料結構基本的知識點,樹裡面有比較特殊的二元樹,這裡就不詳細講解樹的概念了,只是用js實作簡易的二元樹

1 .新增節點
2.移除節點
3.節點最大/最小值
4.中序遍歷
#5.先序遍歷
6.後序遍歷
7 .尋找是否存在指定節點
8.是否為空樹

話不多說,上程式碼,首先是樹的基本單元節點類別

/**
*left:左子树
*right:右子树
*value:节点值
*/
export default class BinaryNode {
	constructor(val) {
		this.value = val;
		this.left = null;
		this.right = null;
	}
}

接下來是二元樹類別程式碼

import BinaryNode from './BinaryNode'

export default class BinarySearchTree {
	constructor() {
		this.root = null;
		this.values = new Array();
	}

	/**
	 * [insert 插入节点]
	 * @param  {[type]} val [description]
	 * @return {[type]}     [description]
	 */
	insert(val) {
		this.values.push(val);
		let node = new BinaryNode(val);
		if (!this.root) {
			this.root = node;
		}else {
			this._insertNode(this.root, node);
		}
	}

	/**
	 * [remove 移除指定值]
	 * @param  {[*]} val [目标值]
	 * @return {[type]}     [description]
	 */
	remove(val) {
		this.root = this._removeNode(this.root, val);
	}

	/**
	 * [search 检索]
	 * @param  {[*]} val [被检索值]
	 * @return {[Boolean]}     [表示是否存在]
	 */
	search(val) {
		let values = this.inOrderTraverse();
		return values.includes(val);
	}

	/**
	 * [min 返回最小值]
	 * @return {[type]} [description]
	 */
	min() {
		let values = this.inOrderTraverse();
		return values[0];
	}

	/**
	 * [max 返回最大值]
	 * @return {[type]} [description]
	 */
	max() {
		let values = this.inOrderTraverse();
		return values[values.length - 1];
	}

	/**
	 * [isEmpty 是否为空二叉树]
	 * @return {Boolean}
	 */
	isEmpty() {
		return this.root === null;
	}

	/**
	 * [inOrderTraverse 中序遍历]
	 * @return {[Array]} [description]
	 */
	inOrderTraverse() {
		let result = new Array();
		this._inOrderTraverseNode(this.root, function(node) {
			result.push(node.value);
		})
		return result;
	}

	/**
	 * [preOrderTraverse 先序遍历]
	 * @return {[Array]} [description]
	 */
	preOrderTraverse() {
		let result = new Array();
		this._preOrderTraverseNode(this.root, function(node) {
			result.push(node.value);
		})
		return result;
	}

	/**
	 * [postOrderTraverse 后序遍历]
	 * @return {[Array]} [description]
	 */
	postOrderTraverse() {
		let result = new Array();
		this._postOrderTraverseNode(this.root, function(node) {
			result.push(node.value);
		})
		return result;
	}

	/**
	 * [_insertNode 在指定节点插入节点]
	 * @param  {[BinaryNode]} node    [目标节点]
	 * @param  {[BinaryNode]} newNode [待插入节点]
	 */
	_insertNode(node, newNode) {
		if (node.value > newNode.value) {
			if (node.left) {
				this._insertNode(node.left, newNode);
			}else {
				node.left = newNode;
			}
		}else {
			if (node.right) {
				this._insertNode(node.right, newNode);
			}else {
				node.right = newNode;
			}
		}
	}

	/**
	 * [_removeNode 移除节点递归]
	 * @param  {[BinaryNode]} node [当前节点]
	 * @param  {[*]} val  [要移的除节点值]
	 * @return {[BinaryNode]}      [当前节点]
	 */
	_removeNode(node, val) {
		if (node === null) {
			return node;
		}
		//递归寻找目标节点
		if (val < node.value) {
			this._removeNode(node.left, val);
			return node;
		}

		if (val > node.value) {
			this._removeNode(node.right, val);
			return node;
		}
		//找到目标节点
		if (val === node.value) {
			//为叶子节点
			if (node.left === null && node.right === null) {
				node = null;
				return node;
			}
			//只有一个子节点
			if (node.left === null) {
				node = node.right;
				return node;
			}else if (node.right === null) {
				node = node.left;
				return node;
			}
			//有两个子节点
			let min_node = this._findMinNode(node);
			node.value = min_node.value;
			node.right = this._removeNode(node.right, min_node.value);
			return node;
		}
	}

	/**
	 * [_findMinNode 查找最小节点]
	 * @param  {[BinaryNode]} node [当前节点]
	 * @return {[BinaryNode]}      [最小的节点]
	 */
	_findMinNode(node) {
		while(node && node.left) {
			node = node.left;
		}
		return node;
	}

	/**
	 * [_inOrderTraverseNode 中序遍历递归]
	 * @param  {[BinaryNode]}   node     [当前节点]
	 * @param  {Function} callback [回调函数]
	 * @return {[type]}            [description]
	 */
	_inOrderTraverseNode(node, callback) {
		if (node) {
			this._inOrderTraverseNode(node.left, callback);
			callback(node);
			this._inOrderTraverseNode(node.right, callback);
		}
	}

	/**
	 * [_preOrderTraverseNode 先序遍历递归]
	 * @param  {[BinaryNode]}   node     [当前节点]
	 * @param  {Function} callback [回调函数]
	 * @return {[type]}            [description]
	 */
	_preOrderTraverseNode(node, callback) {
		if (node) {
			callback(node);
			this._preOrderTraverseNode(node.left, callback);
			this._preOrderTraverseNode(node.right, callback);
		}
	}

	/**
	 * [_postOrderTraverseNode 后序遍历递归]
	 * @param  {[BinaryNode]}   node     [当前节点]
	 * @param  {Function} callback [回调函数]
	 * @return {[type]}            [description]
	 */
	_postOrderTraverseNode(node, callback) {
		if (node) {
			this._postOrderTraverseNode(node.left, callback);
			this._postOrderTraverseNode(node.right, callback);
			callback(node);
		}
	}
}

每個函數的功能都在註釋中,其中這裡對樹的遍歷大量的使用的遞歸,這裡遞歸相對簡單易懂,這裡查找最大最小值偷懶沒有遞歸查找,而是在中序遍歷裡直接取出最大最小值,注意這裡是值,不是樹的節點,實際上查找最小節點的程式碼也作為私有函數寫出來了,只是沒用在最大最小值查找而已

#當然這只是簡單的二元樹,還可以升級成AVL樹等,這裡不再贅述

相關推薦:

JS二元搜尋樹使用詳解

#JS中的二元樹遍歷詳解_javascript技巧

#JS二元樹的先序中序及後序遍歷實作方法

以上是javascript實作二元樹的程式碼介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn