JavaScript描述---二叉查找树


二叉树

二叉树每个节点的子节点不允许超过两个
提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


二叉查找树

二叉查找树是一种特殊的二叉树,相对较小的值保存在左节点中,较大的值保存在右节点中。
在这里插入图片描述

一、二叉查找树的构造

function Node(data, left, right) {
	this.data = data;
	this.left = left;
	this.right = right;
	this.show = show;
}
function show() {
	return this.data;
}
function BST() {
	this.root = null;
	this.insert = insert;
	this.inOrder = inOrder;
	this.preOrder = preOrder;
	this.postOrder = postOrder;
}

二叉查找树插入一个节点的步骤:

  • 设根节点为当前节点;
  • 如果待插入的节点保存的数据小于当前节点,则设新的当前节点为原节点的左节点,反之,执行第四步;
  • 如果当前节点的左节点为null,就将新的节点插入这个位置,退出循环;反之,继续执行下一次循环;
  • 设新的当前节点为原节点的右节点
  • 如果当前节点的右节点为null,就将新的节点插入这个位置,退出循环;反之,继续执行下一次循环;
function insert(data) {
	var n = new Node(data, null, null);
	if (this.root == null) {
		this.root = n;
	} else {
		var current = this.root;
		var parent;
		while (true) {
			parent = current;
			if (data < current.data) {
				current = current.left;
				if (current== null) {
					parent.left = n;
					break;
				}
			} else {
				current = current.right;
				if (current == null) {
					parent.right = n;
					break;
				}
			}
		}
}

二、二叉查找树的遍历

1. 先序遍历

  • 先访问根节点,然后以同样的方式访问左子树和右子树。
function inOrder(node) {
	if (!(node == null)) {
		inOrder(node.left);
		console.log(node.show()+' ');
		inOrder(node.right);
	}
}

2. 中序遍历

  • 先访问左子树,然后访问根节点,最后访问右子树。
function preOrder(node) {
	if (!(node == null)) {
		console.log(node.show() + " ");
		preOrder(node.left);
		preOrder(node.right);
	}
}

3. 后序遍历

  • 先访问左子树,然后访问右子树,最后访问根节点。
function postOrder(node) {
	if (!(node == null)) {
	postOrder(node.left);
	postOrder(node.right);
	console.log(node.show() + " ");
	}
}

测试代码如下:

var nums = new BST();
nums.insert(23);
nums.insert(45);
nums.insert(16);
nums.insert(37);
nums.insert(3);
nums.insert(99);
nums.insert(22);
console.log("Inorder traversal: ");
inOrder(nums.root);
console.log("Preorder traversal: ");
preOrder(nums.root);
console.log("Postorder traversal: ");
postOrder(nums.root);

测试结果:
在这里插入图片描述在这里插入图片描述在这里插入图片描述

三、二叉查找树—查找节点

1. 查找最大值和最小值

//在BST上查找最小值,只需要遍历左子树,直至找到最后一个节点
function getMin(){
	var current=this.root;
	while(!(current.left==null)){
		current=current.left;
	}
	return current.data;
}
//在BST上查找最大值,只需要遍历右子树,直至找到最后一个节点
function getMax(){
	var current=this.root;
	while(!(current.right==null)){
		current=current.right;
	}
	return current.data;
}

2.查找给定值

function find(data){
	var current=this.root;
	while(current!=null){
		if(current.data==data){
        	return current;
        }
        //如果查找的值小于根节点,则向左遍历
        else if(data<current.data){
        	current=current.left;
        }
         //如果查找的值大于根节点,则向右遍历
        else{
			current=current.right;
        }
   }
   return null;
}

四、二叉查找树—删除节点

此部分转载自https://blog.csdn.net/isea533/article/details/80345507.

初始状态如下图所示,我们可以按照 50, 30, 80, 20, 35, 34, 32, 40, 70, 75, 100 的顺序插入到树中,就会产生下图所示的树。
在这里插入图片描述

1. 没有左右子节点时

在我们图中,符合这个条件的有 20,32,40,75,100,随便找个 20 来演示删除该节点:
在这里插入图片描述
这种情况是最简单的,我们只需要删除该节点和父节点的关系即可。删除的时候需要先判断自己和父节点的关系是左侧还是右侧,如下:

//这里忽略了父节点不存在的情况,最后会巧妙的处理这种情况
if(node.parent.left == node){
    node.parent.left = null;
} else {
    node.parent.right = null;
}  

2. 存在左节点或者右节点时

满足这个情况的节点有 34, 70 两个节点,这里以 70 为例,如下图所示:
在这里插入图片描述

//先找到子节点,不需要管他是左是右
var child = null;
if(node.left != null){
    child = node.left;
} else {
    child = node.right;
}
//这里忽略了父节点不存在的情况,最后会巧妙的处理这种情况
//将父节点和子节点建立关系
if(node.parent.left == node){
    node.parent.left = child;
} else {
    node.parent.right = child;
}
child.parent = node.parent;

3. 同时存在左右子节点

满足同时存在左右节点的节点有 50,30,80,35 这 4 个节点,30 看起来更复杂,我们以 30 为例,,主要有两种方式:要么查找待删除节点左子树上的最大值,要么查找其右子树的最小值,这里以后者为例。

在这里插入图片描述

//获取待删除节点节点右子树的最小值,此部分的代码较简单,因此不做详细说明
var tempNode=getSmallest(node.right);
//转移值
node.data=tempNode.data;
//后续变成删除tempNode,就变成了前两种情况
//在图示例子中,就是第一种没有子节点的情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值