二叉搜索树(Binary Search Tree)

二叉搜索树,也叫做二叉排序树。这种结构查找元素非常的高效。

在JS里面构建这种结构,有2种方法

1)通过嵌套的对象 

2)通过嵌套的数组

下面我们给出嵌套的对象来实现这种结构

/*
	二叉搜索树,二叉排序树,Binary Search Tree
	这里我们使用嵌套的对象(nested object)
*/
function BinarySearchTree() {
	var Node = function (key) {
		this.key = key;
		this.left = null;
		this.right = null;
	}

	var root = null;

	/*插入节点*/
	this.insert = function (key) {
		var new_node = new Node(key);
		if(root == null) {
			root = new_node;
		} else {
			insertNode(root, new_node);
		}

		function insertNode(parent, new_node) {
			if(parent.key > new_node.key) {
				if(parent.left == null) {
					parent.left = new_node;
				} else {
					insertNode(parent.left, new_node);
				}
			} else {
				if(parent.right == null) {
					parent.right = new_node;
				}else {
					insertNode(parent.right, new_node);
				}
			}
		}
	}

	/* 
		注意
		实际上该函数应该是不存在的
		为了测试方便引入的
		为了防止对root 节点进行修改。 
	*/
	this.getRoot = function () {
		return root;
	}


	/*
		搜索节点
		使用哪种方法都可以
	*/
	// this.search = function (key) {
	// 	if(root == null) {
	// 		return false;
	// 	}

	// 	if(root.key == key) {
	// 		return true;
	// 	}

	// 	if(root.key > key) {
	// 		return searchTree(root.left);
	// 	}

	// 	if(root.key < key) {
	// 		return searchTree(root.right);
	// 	}

	// 	function searchTree(parent) {
	// 		if(parent == null) {
	// 			return false;
	// 		}

	// 		if(parent.key == key) {
	// 			return true;
	// 		}

	// 		if(parent.key > key) {
	// 			return searchTree(parent.left);   // 这里需要return
	// 		}

	// 		if(parent.key < key) {
	// 			return searchTree(parent.right);
	// 		}
	// 	}
	// } 

	this.search = function (key, parent) {
		if(parent === null) {   // 注意这里需要使用 === ,					
			return false;       //	因为 undefined == null 显示的是true  
		}

		var current = parent || root;
		if(current == null) {
			return false;
		}

		if(current.key == key) {
			return true;
		}

		if(current.key > key) {
			return this.search(key, current.left);
		}

		if(current.key < key) {
			return this.search(key, current.right);
		}

	}

	/*中序遍历*/
	this.inOrderTraverse = function () {
		if(root == null) {
			return;
		}

		inOrderTraverseNode(root.left);
		console.log(root.key);
		inOrderTraverseNode(root.right);

		/* Here is an auxiliary function */
		function inOrderTraverseNode(parent) {
			if(parent == null) {
				return;
			}

			inOrderTraverseNode(parent.left);
			console.log(parent.key);
			inOrderTraverseNode(parent.right);
		}
	}

	/*前序遍历*/
	this.preOrderTraverse = function () {
		if(root == null) {
			return;
		}

		console.log(root.key);
		preOrderTraverse(root.left);
		preOrderTraverse(root.right);

		/*Here is an auxiliary function*/
		function preOrderTraverse(parent) {
			if(parent == null) {
				return;
			}
			console.log(parent.key);
			preOrderTraverse(parent.left);
			preOrderTraverse(parent.right);
		}
	}

	/*后序遍历*/
	this.postOrderTraverse = function () {
		if(root == null) {
			return;
		}

		postOrderTraverseNode(root.left);
		postOrderTraverseNode(root.right);
		console.log(root.key);

		/*Here is an auxiliary function*/
		function postOrderTraverseNode(parent) {
			if(parent == null) {
				return;
			}

			postOrderTraverseNode(parent.left);
			postOrderTraverseNode(parent.right);
			console.log(parent.key);
		}
	}

	/*
		返回BST树中的最小值
		1) 使用递归
		2)使用循环
	*/
	// this.min = function () {
	// 	var current = root;
	// 	while(current.left != null) {
	// 		current = current.left;
	// 	}

	// 	return current.key;
	// }


	this.min = function () {
		if(root == null) {
			return;
		}

		return minNode(root);

		function minNode(parent) {
			if(parent.left == null) {
				return parent.key;
			} 
			return minNode(parent.left);
		}
	}

	/*返回BST树中的最大值*/
	// this.max = function () {
	// 	var current = root;
	// 	while(current.right != null) {
	// 		current = current.right;
	// 	}

	// 	return current.key;
	// }

	this.max = function () {
		if(root == null) {
			return;
		}

		return maxNode(root);
		
		function maxNode(parent) {
			if(parent.right == null) {
				return parent.key;
			}

			return maxNode(parent.right);
		} 
	}

	/*移除树中的节点*/
	this.remove = function (key) {
		root = removeNode(root, key);

		/* Here is an auxiliary function */
		function removeNode(node, key) {
			if(node == null) {
				return null;
			}

			if(key < node.key) {
				node.left = removeNode(node.left, key);
				return node;
			} else if(key > node.key) {
				node.right = removeNode(node.right, key);
				return node;
			} else {

				/*移除的是叶子节点*/
				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;
				}

				/*有两个叶子节点*/
				var aux = findMinNode(node.right);
				node.key = aux.key;
				node.right = removeNode(node.right, aux.key);
				return node
			}

			/*寻找最小的节点*/
			function findMinNode(node) {
				if(node == null) {
					return;
				}
				var current = node;
				while(current.left != null) {
					current = current.left;
				}

				return current;
			}
		}
	}
}


var arr = [6, 20, 7, 9, 6, 2, 3, 1, 8, 4];
var bst = new BinarySearchTree();
for(var i=0; i<arr.length; ++i) {
	bst.insert(arr[i]);
}

var root = bst.getRoot();

console.log(bst.search(6));



猜你喜欢

转载自blog.csdn.net/qq_21058391/article/details/78162602